@wyw-in-js/transform 0.5.4 → 0.6.0

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.
@@ -19,7 +19,12 @@ export default function dynamicImport(babel) {
19
19
  path.replaceWith(t.callExpression(t.identifier('__wyw_dynamic_import'), [t.cloneNode(moduleName.node, true, true)]));
20
20
  return;
21
21
  }
22
- throw new Error('Dynamic import argument must be a string or a template literal');
22
+
23
+ // Throw an error if this import will be reached during evaluation
24
+ // throw new Error(
25
+ // 'Dynamic import argument must be a string or a template literal'
26
+ // );
27
+ path.replaceWith(t.callExpression(t.arrowFunctionExpression([], t.blockStatement([t.throwStatement(t.newExpression(t.identifier('Error'), [t.stringLiteral('Dynamic import argument must be a string or a template literal')]))])), []));
23
28
  }
24
29
  }
25
30
  }
@@ -1 +1 @@
1
- {"version":3,"file":"dynamic-import.js","names":["dynamicImport","babel","types","t","name","visitor","CallExpression","path","get","isImport","moduleName","isStringLiteral","replaceWith","callExpression","identifier","stringLiteral","node","value","isTemplateLiteral","cloneNode","Error"],"sources":["../../src/plugins/dynamic-import.ts"],"sourcesContent":["import type { NodePath, PluginObj } from '@babel/core';\n\nimport type { Core } from '../babel';\n\n/**\n * The plugin that replaces `import()` with `__wyw_dynamic_import` as Node VM does not support dynamic imports yet.\n */\nexport default function dynamicImport(babel: Core): PluginObj {\n const { types: t } = babel;\n\n return {\n name: '@wyw-in-js/transform/dynamic-import',\n visitor: {\n CallExpression(path) {\n if (path.get('callee').isImport()) {\n const moduleName = path.get('arguments.0') as NodePath;\n\n if (moduleName.isStringLiteral()) {\n path.replaceWith(\n t.callExpression(t.identifier('__wyw_dynamic_import'), [\n t.stringLiteral(moduleName.node.value),\n ])\n );\n return;\n }\n\n if (moduleName.isTemplateLiteral()) {\n path.replaceWith(\n t.callExpression(t.identifier('__wyw_dynamic_import'), [\n t.cloneNode(moduleName.node, true, true),\n ])\n );\n return;\n }\n\n throw new Error(\n 'Dynamic import argument must be a string or a template literal'\n );\n }\n },\n },\n };\n}\n"],"mappings":"AAIA;AACA;AACA;AACA,eAAe,SAASA,aAAaA,CAACC,KAAW,EAAa;EAC5D,MAAM;IAAEC,KAAK,EAAEC;EAAE,CAAC,GAAGF,KAAK;EAE1B,OAAO;IACLG,IAAI,EAAE,qCAAqC;IAC3CC,OAAO,EAAE;MACPC,cAAcA,CAACC,IAAI,EAAE;QACnB,IAAIA,IAAI,CAACC,GAAG,CAAC,QAAQ,CAAC,CAACC,QAAQ,CAAC,CAAC,EAAE;UACjC,MAAMC,UAAU,GAAGH,IAAI,CAACC,GAAG,CAAC,aAAa,CAAa;UAEtD,IAAIE,UAAU,CAACC,eAAe,CAAC,CAAC,EAAE;YAChCJ,IAAI,CAACK,WAAW,CACdT,CAAC,CAACU,cAAc,CAACV,CAAC,CAACW,UAAU,CAAC,sBAAsB,CAAC,EAAE,CACrDX,CAAC,CAACY,aAAa,CAACL,UAAU,CAACM,IAAI,CAACC,KAAK,CAAC,CACvC,CACH,CAAC;YACD;UACF;UAEA,IAAIP,UAAU,CAACQ,iBAAiB,CAAC,CAAC,EAAE;YAClCX,IAAI,CAACK,WAAW,CACdT,CAAC,CAACU,cAAc,CAACV,CAAC,CAACW,UAAU,CAAC,sBAAsB,CAAC,EAAE,CACrDX,CAAC,CAACgB,SAAS,CAACT,UAAU,CAACM,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CACzC,CACH,CAAC;YACD;UACF;UAEA,MAAM,IAAII,KAAK,CACb,gEACF,CAAC;QACH;MACF;IACF;EACF,CAAC;AACH"}
1
+ {"version":3,"file":"dynamic-import.js","names":["dynamicImport","babel","types","t","name","visitor","CallExpression","path","get","isImport","moduleName","isStringLiteral","replaceWith","callExpression","identifier","stringLiteral","node","value","isTemplateLiteral","cloneNode","arrowFunctionExpression","blockStatement","throwStatement","newExpression"],"sources":["../../src/plugins/dynamic-import.ts"],"sourcesContent":["import type { NodePath, PluginObj } from '@babel/core';\n\nimport type { Core } from '../babel';\n\n/**\n * The plugin that replaces `import()` with `__wyw_dynamic_import` as Node VM does not support dynamic imports yet.\n */\nexport default function dynamicImport(babel: Core): PluginObj {\n const { types: t } = babel;\n\n return {\n name: '@wyw-in-js/transform/dynamic-import',\n visitor: {\n CallExpression(path) {\n if (path.get('callee').isImport()) {\n const moduleName = path.get('arguments.0') as NodePath;\n\n if (moduleName.isStringLiteral()) {\n path.replaceWith(\n t.callExpression(t.identifier('__wyw_dynamic_import'), [\n t.stringLiteral(moduleName.node.value),\n ])\n );\n return;\n }\n\n if (moduleName.isTemplateLiteral()) {\n path.replaceWith(\n t.callExpression(t.identifier('__wyw_dynamic_import'), [\n t.cloneNode(moduleName.node, true, true),\n ])\n );\n return;\n }\n\n // Throw an error if this import will be reached during evaluation\n // throw new Error(\n // 'Dynamic import argument must be a string or a template literal'\n // );\n path.replaceWith(\n t.callExpression(\n t.arrowFunctionExpression(\n [],\n t.blockStatement([\n t.throwStatement(\n t.newExpression(t.identifier('Error'), [\n t.stringLiteral(\n 'Dynamic import argument must be a string or a template literal'\n ),\n ])\n ),\n ])\n ),\n []\n )\n );\n }\n },\n },\n };\n}\n"],"mappings":"AAIA;AACA;AACA;AACA,eAAe,SAASA,aAAaA,CAACC,KAAW,EAAa;EAC5D,MAAM;IAAEC,KAAK,EAAEC;EAAE,CAAC,GAAGF,KAAK;EAE1B,OAAO;IACLG,IAAI,EAAE,qCAAqC;IAC3CC,OAAO,EAAE;MACPC,cAAcA,CAACC,IAAI,EAAE;QACnB,IAAIA,IAAI,CAACC,GAAG,CAAC,QAAQ,CAAC,CAACC,QAAQ,CAAC,CAAC,EAAE;UACjC,MAAMC,UAAU,GAAGH,IAAI,CAACC,GAAG,CAAC,aAAa,CAAa;UAEtD,IAAIE,UAAU,CAACC,eAAe,CAAC,CAAC,EAAE;YAChCJ,IAAI,CAACK,WAAW,CACdT,CAAC,CAACU,cAAc,CAACV,CAAC,CAACW,UAAU,CAAC,sBAAsB,CAAC,EAAE,CACrDX,CAAC,CAACY,aAAa,CAACL,UAAU,CAACM,IAAI,CAACC,KAAK,CAAC,CACvC,CACH,CAAC;YACD;UACF;UAEA,IAAIP,UAAU,CAACQ,iBAAiB,CAAC,CAAC,EAAE;YAClCX,IAAI,CAACK,WAAW,CACdT,CAAC,CAACU,cAAc,CAACV,CAAC,CAACW,UAAU,CAAC,sBAAsB,CAAC,EAAE,CACrDX,CAAC,CAACgB,SAAS,CAACT,UAAU,CAACM,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CACzC,CACH,CAAC;YACD;UACF;;UAEA;UACA;UACA;UACA;UACAT,IAAI,CAACK,WAAW,CACdT,CAAC,CAACU,cAAc,CACdV,CAAC,CAACiB,uBAAuB,CACvB,EAAE,EACFjB,CAAC,CAACkB,cAAc,CAAC,CACflB,CAAC,CAACmB,cAAc,CACdnB,CAAC,CAACoB,aAAa,CAACpB,CAAC,CAACW,UAAU,CAAC,OAAO,CAAC,EAAE,CACrCX,CAAC,CAACY,aAAa,CACb,gEACF,CAAC,CACF,CACH,CAAC,CACF,CACH,CAAC,EACD,EACF,CACF,CAAC;QACH;MACF;IACF;EACF,CAAC;AACH"}
@@ -36,7 +36,7 @@ export function preeval(babel, options) {
36
36
  });
37
37
  if (isFeatureEnabled(options.features, 'dangerousCodeRemover', filename)) {
38
38
  log('start', 'Strip all JSX and browser related stuff');
39
- eventEmitter.perf('transform:preeval:removeDangerousCode', () => removeDangerousCode(file.path));
39
+ eventEmitter.perf('transform:preeval:removeDangerousCode', () => removeDangerousCode(file.path, options.codeRemover));
40
40
  }
41
41
  },
42
42
  visitor: {},
@@ -1 +1 @@
1
- {"version":3,"file":"preeval.js","names":["isFeatureEnabled","logger","applyProcessors","EventEmitter","addIdentifierToWywPreval","getFileIdx","removeDangerousCode","invalidateTraversalCache","preeval","babel","options","types","t","eventEmitter","dummy","name","pre","file","filename","opts","log","extend","rootScope","scope","processors","perf","path","processor","dependencies","forEach","dependency","ex","type","doEvaltimeReplacement","push","features","visitor","post","length","metadata","wywInJS","replacements","rules","wywPreval","getData","wywExport","expressionStatement","assignmentExpression","memberExpression","identifier","objectExpression","pushContainer"],"sources":["../../src/plugins/preeval.ts"],"sourcesContent":["/**\n * This file is a babel preset used to transform files inside evaluators.\n * It works the same as main `babel/extract` preset, but do not evaluate lazy dependencies.\n */\nimport type { BabelFile, PluginObj } from '@babel/core';\n\nimport type { StrictOptions } from '@wyw-in-js/shared';\nimport { isFeatureEnabled, logger } from '@wyw-in-js/shared';\n\nimport { applyProcessors } from '../utils/getTagProcessor';\nimport type { Core } from '../babel';\nimport type { IPluginState } from '../types';\nimport { EventEmitter } from '../utils/EventEmitter';\nimport { addIdentifierToWywPreval } from '../utils/addIdentifierToWywPreval';\nimport { getFileIdx } from '../utils/getFileIdx';\nimport { removeDangerousCode } from '../utils/removeDangerousCode';\nimport { invalidateTraversalCache } from '../utils/traversalCache';\n\nexport type PreevalOptions = Pick<\n StrictOptions,\n | 'classNameSlug'\n | 'displayName'\n | 'extensions'\n | 'evaluate'\n | 'features'\n | 'tagResolver'\n> & { eventEmitter?: EventEmitter };\n\nexport function preeval(\n babel: Core,\n options: PreevalOptions\n): PluginObj<IPluginState & { onFinish: () => void }> {\n const { types: t } = babel;\n const eventEmitter = options.eventEmitter ?? EventEmitter.dummy;\n return {\n name: '@wyw-in-js/transform/preeval',\n pre(file: BabelFile) {\n const filename = file.opts.filename!;\n const log = logger.extend('preeval').extend(getFileIdx(filename));\n\n log('start', 'Looking for template literals…');\n\n const rootScope = file.scope;\n this.processors = [];\n\n eventEmitter.perf('transform:preeval:processTemplate', () => {\n applyProcessors(file.path, file.opts, options, (processor) => {\n processor.dependencies.forEach((dependency) => {\n if (dependency.ex.type === 'Identifier') {\n addIdentifierToWywPreval(rootScope, dependency.ex.name);\n }\n });\n\n processor.doEvaltimeReplacement();\n this.processors.push(processor);\n });\n });\n\n if (\n isFeatureEnabled(options.features, 'dangerousCodeRemover', filename)\n ) {\n log('start', 'Strip all JSX and browser related stuff');\n eventEmitter.perf('transform:preeval:removeDangerousCode', () =>\n removeDangerousCode(file.path)\n );\n }\n },\n visitor: {},\n post(file: BabelFile) {\n const log = logger\n .extend('preeval')\n .extend(getFileIdx(file.opts.filename!));\n\n invalidateTraversalCache(file.path);\n\n if (this.processors.length === 0) {\n log('end', \"We didn't find any wyw-in-js template literals\");\n\n // We didn't find any wyw-in-js template literals.\n return;\n }\n\n this.file.metadata.wywInJS = {\n processors: this.processors,\n replacements: [],\n rules: {},\n dependencies: [],\n };\n\n const wywPreval = file.path.getData('__wywPreval');\n if (!wywPreval) {\n // Event if there is no dependencies, we still need to add __wywPreval\n const wywExport = t.expressionStatement(\n t.assignmentExpression(\n '=',\n t.memberExpression(\n t.identifier('exports'),\n t.identifier('__wywPreval')\n ),\n t.objectExpression([])\n )\n );\n\n file.path.pushContainer('body', wywExport);\n }\n\n log('end', '__wywPreval has been added');\n },\n };\n}\n\nexport default preeval;\n"],"mappings":"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"}
1
+ {"version":3,"file":"preeval.js","names":["isFeatureEnabled","logger","applyProcessors","EventEmitter","addIdentifierToWywPreval","getFileIdx","removeDangerousCode","invalidateTraversalCache","preeval","babel","options","types","t","eventEmitter","dummy","name","pre","file","filename","opts","log","extend","rootScope","scope","processors","perf","path","processor","dependencies","forEach","dependency","ex","type","doEvaltimeReplacement","push","features","codeRemover","visitor","post","length","metadata","wywInJS","replacements","rules","wywPreval","getData","wywExport","expressionStatement","assignmentExpression","memberExpression","identifier","objectExpression","pushContainer"],"sources":["../../src/plugins/preeval.ts"],"sourcesContent":["/**\n * This file is a babel preset used to transform files inside evaluators.\n * It works the same as main `babel/extract` preset, but do not evaluate lazy dependencies.\n */\nimport type { BabelFile, PluginObj } from '@babel/core';\n\nimport type { StrictOptions } from '@wyw-in-js/shared';\nimport { isFeatureEnabled, logger } from '@wyw-in-js/shared';\n\nimport { applyProcessors } from '../utils/getTagProcessor';\nimport type { Core } from '../babel';\nimport type { IPluginState } from '../types';\nimport { EventEmitter } from '../utils/EventEmitter';\nimport { addIdentifierToWywPreval } from '../utils/addIdentifierToWywPreval';\nimport { getFileIdx } from '../utils/getFileIdx';\nimport { removeDangerousCode } from '../utils/removeDangerousCode';\nimport { invalidateTraversalCache } from '../utils/traversalCache';\n\nexport type PreevalOptions = Pick<\n StrictOptions,\n | 'classNameSlug'\n | 'codeRemover'\n | 'displayName'\n | 'extensions'\n | 'evaluate'\n | 'features'\n | 'tagResolver'\n> & { eventEmitter?: EventEmitter };\n\nexport function preeval(\n babel: Core,\n options: PreevalOptions\n): PluginObj<IPluginState & { onFinish: () => void }> {\n const { types: t } = babel;\n const eventEmitter = options.eventEmitter ?? EventEmitter.dummy;\n return {\n name: '@wyw-in-js/transform/preeval',\n pre(file: BabelFile) {\n const filename = file.opts.filename!;\n const log = logger.extend('preeval').extend(getFileIdx(filename));\n\n log('start', 'Looking for template literals…');\n\n const rootScope = file.scope;\n this.processors = [];\n\n eventEmitter.perf('transform:preeval:processTemplate', () => {\n applyProcessors(file.path, file.opts, options, (processor) => {\n processor.dependencies.forEach((dependency) => {\n if (dependency.ex.type === 'Identifier') {\n addIdentifierToWywPreval(rootScope, dependency.ex.name);\n }\n });\n\n processor.doEvaltimeReplacement();\n this.processors.push(processor);\n });\n });\n\n if (\n isFeatureEnabled(options.features, 'dangerousCodeRemover', filename)\n ) {\n log('start', 'Strip all JSX and browser related stuff');\n eventEmitter.perf('transform:preeval:removeDangerousCode', () =>\n removeDangerousCode(file.path, options.codeRemover)\n );\n }\n },\n visitor: {},\n post(file: BabelFile) {\n const log = logger\n .extend('preeval')\n .extend(getFileIdx(file.opts.filename!));\n\n invalidateTraversalCache(file.path);\n\n if (this.processors.length === 0) {\n log('end', \"We didn't find any wyw-in-js template literals\");\n\n // We didn't find any wyw-in-js template literals.\n return;\n }\n\n this.file.metadata.wywInJS = {\n processors: this.processors,\n replacements: [],\n rules: {},\n dependencies: [],\n };\n\n const wywPreval = file.path.getData('__wywPreval');\n if (!wywPreval) {\n // Event if there is no dependencies, we still need to add __wywPreval\n const wywExport = t.expressionStatement(\n t.assignmentExpression(\n '=',\n t.memberExpression(\n t.identifier('exports'),\n t.identifier('__wywPreval')\n ),\n t.objectExpression([])\n )\n );\n\n file.path.pushContainer('body', wywExport);\n }\n\n log('end', '__wywPreval has been added');\n },\n };\n}\n\nexport default preeval;\n"],"mappings":"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"}
@@ -1,7 +1,9 @@
1
+ import { types as t } from '@babel/core';
1
2
  import { nonType } from './findIdentifiers';
2
3
  import { isUnnecessaryReactCall } from './isUnnecessaryReactCall';
3
4
  import { applyAction, removeWithRelated } from './scopeHelpers';
4
5
  import { JSXElementsRemover } from './visitors/JSXElementsRemover';
6
+ import { collectExportsAndImports } from './collectExportsAndImports';
5
7
  const isGlobal = id => {
6
8
  if (!nonType(id)) {
7
9
  return false;
@@ -31,7 +33,106 @@ const getPropertyName = path => {
31
33
  }
32
34
  return null;
33
35
  };
34
- export const removeDangerousCode = programPath => {
36
+ const getImport = path => {
37
+ const programPath = path.findParent(p => p.isProgram());
38
+ if (!programPath) {
39
+ return undefined;
40
+ }
41
+ const {
42
+ imports
43
+ } = collectExportsAndImports(programPath);
44
+ if (path.isIdentifier()) {
45
+ const binding = path.scope.getBinding(path.node.name);
46
+ const matched = binding && imports.find(imp => imp.imported !== 'side-effect' && binding.path.isAncestor(imp.local));
47
+ if (matched) {
48
+ return [matched.source, matched.imported];
49
+ }
50
+ }
51
+ if (path.isMemberExpression()) {
52
+ const leftPath = path.get('object');
53
+ if (!leftPath.isIdentifier()) {
54
+ // Nested member expression. Not supported yet.
55
+ return undefined;
56
+ }
57
+ const rightPath = path.get('property');
58
+ if (!rightPath.isIdentifier()) {
59
+ return undefined;
60
+ }
61
+ const binding = path.scope.getBinding(leftPath.node.name);
62
+ const matched = binding && imports.find(imp => imp.imported !== 'side-effect' && binding.path.isAncestor(imp.local));
63
+ if (matched) {
64
+ return [matched.source, rightPath.node.name];
65
+ }
66
+ }
67
+ return undefined;
68
+ };
69
+ const getTypeImport = path => {
70
+ // We are looking for either Identifier or TSQualifiedName in path
71
+ if (path.isIdentifier()) {
72
+ const binding = path.scope.getBinding(path.node.name);
73
+ if (!binding) {
74
+ return undefined;
75
+ }
76
+ if (!binding.path.isImportSpecifier() || !binding.path.parentPath.isImportDeclaration()) {
77
+ return undefined;
78
+ }
79
+ const importDeclaration = binding.path.parentPath;
80
+ const imported = binding.path.get('imported');
81
+ const source = importDeclaration.node.source.value;
82
+ const importedNode = imported.node;
83
+ return [source, t.isIdentifier(importedNode) ? importedNode.name : importedNode.value];
84
+ }
85
+ if (path.isTSQualifiedName()) {
86
+ const leftPath = path.get('left');
87
+ if (!leftPath.isIdentifier()) {
88
+ // Nested type. Not supported yet.
89
+ return undefined;
90
+ }
91
+ const rightPath = path.get('right');
92
+ const binding = path.scope.getBinding(leftPath.node.name);
93
+ if (!binding) {
94
+ return undefined;
95
+ }
96
+ if (!binding.path.isImportDefaultSpecifier() && !binding.path.isImportNamespaceSpecifier() || !binding.path.parentPath.isImportDeclaration()) {
97
+ return undefined;
98
+ }
99
+ return [binding.path.parentPath.node.source.value, rightPath.node.name];
100
+ }
101
+ return undefined;
102
+ };
103
+ const isTypeMatch = (id, types) => {
104
+ const typeAnnotation = id.get('typeAnnotation');
105
+ if (!typeAnnotation.isTSTypeAnnotation()) {
106
+ return false;
107
+ }
108
+ const typeReference = typeAnnotation.get('typeAnnotation');
109
+ if (!typeReference.isTSTypeReference()) {
110
+ return false;
111
+ }
112
+ const typeName = typeReference.get('typeName');
113
+ const matchedImport = getTypeImport(typeName);
114
+ return matchedImport !== undefined && matchedImport[0] in types && types[matchedImport[0]].includes(matchedImport[1]);
115
+ };
116
+ const isHOC = (path, hocs) => {
117
+ let calleePath = path;
118
+ while (calleePath.isCallExpression()) {
119
+ calleePath = calleePath.get('callee');
120
+ }
121
+ const matchedImport = getImport(calleePath);
122
+ return matchedImport !== undefined && matchedImport[0] in hocs && hocs[matchedImport[0]].includes(matchedImport[1]);
123
+ };
124
+ const defaultPlaceholder = '...';
125
+ const defaultReactComponentTypes = ['ExoticComponent', 'FC', 'ForwardRefExoticComponent', 'FunctionComponent', 'LazyExoticComponent', 'MemoExoticComponent', 'NamedExoticComponent'];
126
+ export const removeDangerousCode = (programPath, options) => {
127
+ const hocs = options?.hocs ?? {};
128
+ const componentTypes = options?.componentTypes ?? {
129
+ react: [defaultPlaceholder]
130
+ };
131
+ if (Array.isArray(componentTypes.react) && componentTypes.react.includes(defaultPlaceholder)) {
132
+ const idx = componentTypes.react.indexOf(defaultPlaceholder);
133
+ componentTypes.react = [...componentTypes.react];
134
+ componentTypes.react.splice(idx, 1, ...defaultReactComponentTypes);
135
+ }
35
136
  programPath.traverse({
36
137
  // JSX can be replaced with a dummy value,
37
138
  // but we have to do it after we processed template tags.
@@ -40,6 +141,9 @@ export const removeDangerousCode = programPath => {
40
141
  if (isUnnecessaryReactCall(p)) {
41
142
  JSXElementsRemover(p);
42
143
  }
144
+ if (isHOC(p, hocs)) {
145
+ applyAction(['replace', p, t.arrowFunctionExpression([], t.nullLiteral())]);
146
+ }
43
147
  }
44
148
  },
45
149
  JSXElement: {
@@ -118,6 +222,14 @@ export const removeDangerousCode = programPath => {
118
222
  type: 'StringLiteral',
119
223
  value: 'undefined'
120
224
  }]);
225
+ },
226
+ VariableDeclarator(p) {
227
+ const id = p.get('id');
228
+ const init = p.get('init');
229
+ if (id.isIdentifier() && isTypeMatch(id, componentTypes) && init.isExpression()) {
230
+ // Variable is typed as a React component. We can replace its value with a null-function.
231
+ applyAction(['replace', init, t.arrowFunctionExpression([], t.nullLiteral())]);
232
+ }
121
233
  }
122
234
  }, {
123
235
  globals: [],
@@ -1 +1 @@
1
- {"version":3,"file":"removeDangerousCode.js","names":["nonType","isUnnecessaryReactCall","applyAction","removeWithRelated","JSXElementsRemover","isGlobal","id","scope","name","node","hasBinding","hasGlobal","ssrCheckFields","Set","forbiddenGlobals","isBrowserGlobal","has","isSSRCheckField","getPropertyName","path","isIdentifier","isStringLiteral","value","removeDangerousCode","programPath","traverse","CallExpression","enter","p","JSXElement","JSXFragment","MemberExpression","state","obj","get","prop","windowScoped","add","globals","filter","MetaProperty","Identifier","find","parent","isTSTypeReference","parentPath","isUnaryExpression","operator","isTSTypeQuery","isClassProperty","isMemberExpression","key","push","UnaryExpression","arg","type"],"sources":["../../src/utils/removeDangerousCode.ts"],"sourcesContent":["import type { NodePath } from '@babel/core';\nimport type { Identifier, Program } from '@babel/types';\n\nimport { nonType } from './findIdentifiers';\nimport { isUnnecessaryReactCall } from './isUnnecessaryReactCall';\nimport { applyAction, removeWithRelated } from './scopeHelpers';\nimport { JSXElementsRemover } from './visitors/JSXElementsRemover';\n\nconst isGlobal = (id: NodePath<Identifier>): boolean => {\n if (!nonType(id)) {\n return false;\n }\n\n const { scope } = id;\n const { name } = id.node;\n return !scope.hasBinding(name) && scope.hasGlobal(name);\n};\n\nconst ssrCheckFields = new Set([\n 'document',\n 'location',\n 'navigator',\n 'sessionStorage',\n 'localStorage',\n 'window',\n]);\n\nconst forbiddenGlobals = new Set([\n ...ssrCheckFields,\n '$RefreshReg$',\n 'XMLHttpRequest',\n 'clearImmediate',\n 'clearInterval',\n 'clearTimeout',\n 'fetch',\n 'navigator',\n 'setImmediate',\n 'setInterval',\n 'setTimeout',\n]);\n\nconst isBrowserGlobal = (id: NodePath<Identifier>) => {\n return forbiddenGlobals.has(id.node.name) && isGlobal(id);\n};\n\nconst isSSRCheckField = (id: NodePath<Identifier>) => {\n return ssrCheckFields.has(id.node.name) && isGlobal(id);\n};\n\nconst getPropertyName = (path: NodePath): string | null => {\n if (path.isIdentifier()) {\n return path.node.name;\n }\n\n if (path.isStringLiteral()) {\n return path.node.value;\n }\n\n return null;\n};\n\nexport const removeDangerousCode = (programPath: NodePath<Program>) => {\n programPath.traverse(\n {\n // JSX can be replaced with a dummy value,\n // but we have to do it after we processed template tags.\n CallExpression: {\n enter(p) {\n if (isUnnecessaryReactCall(p)) {\n JSXElementsRemover(p);\n }\n },\n },\n JSXElement: {\n enter: JSXElementsRemover,\n },\n JSXFragment: {\n enter: JSXElementsRemover,\n },\n MemberExpression(p, state) {\n const obj = p.get('object');\n const prop = p.get('property');\n if (!obj.isIdentifier({ name: 'window' })) {\n return;\n }\n\n const name = getPropertyName(prop);\n if (!name) {\n return;\n }\n\n state.windowScoped.add(name);\n // eslint-disable-next-line no-param-reassign\n state.globals = state.globals.filter((id) => {\n if (id.node.name === name) {\n removeWithRelated([id]);\n return false;\n }\n\n return true;\n });\n },\n MetaProperty(p) {\n // Remove all references to `import.meta`\n removeWithRelated([p]);\n },\n Identifier(p, state) {\n if (p.find((parent) => parent.isTSTypeReference())) {\n // don't mess with TS type references\n return;\n }\n if (isBrowserGlobal(p)) {\n if (\n p.find(\n (parentPath) =>\n parentPath.isUnaryExpression({ operator: 'typeof' }) ||\n parentPath.isTSTypeQuery()\n )\n ) {\n // Ignore `typeof window` expressions\n return;\n }\n\n if (p.parentPath.isClassProperty()) {\n // ignore class property decls\n return;\n }\n if (p.parentPath.isMemberExpression() && p.key === 'property') {\n // ignore e.g this.fetch()\n // window.fetch will be handled by the windowScoped block below\n return;\n }\n\n removeWithRelated([p]);\n\n return;\n }\n\n if (state.windowScoped.has(p.node.name)) {\n removeWithRelated([p]);\n } else if (isGlobal(p)) {\n state.globals.push(p);\n }\n },\n\n // Since we can use happy-dom, typical SSR checks may not work as expected.\n // We need to detect them and replace with an \"undefined\" literal.\n UnaryExpression(p) {\n if (p.node.operator !== 'typeof') {\n return;\n }\n const arg = p.get('argument');\n if (!arg.isIdentifier() || !isSSRCheckField(arg)) {\n return;\n }\n\n applyAction([\n 'replace',\n p,\n { type: 'StringLiteral', value: 'undefined' },\n ]);\n },\n },\n {\n globals: [] as NodePath<Identifier>[],\n windowScoped: new Set<string>(),\n }\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"removeDangerousCode.js","names":["types","t","nonType","isUnnecessaryReactCall","applyAction","removeWithRelated","JSXElementsRemover","collectExportsAndImports","isGlobal","id","scope","name","node","hasBinding","hasGlobal","ssrCheckFields","Set","forbiddenGlobals","isBrowserGlobal","has","isSSRCheckField","getPropertyName","path","isIdentifier","isStringLiteral","value","getImport","programPath","findParent","p","isProgram","undefined","imports","binding","getBinding","matched","find","imp","imported","isAncestor","local","source","isMemberExpression","leftPath","get","rightPath","getTypeImport","isImportSpecifier","parentPath","isImportDeclaration","importDeclaration","importedNode","isTSQualifiedName","isImportDefaultSpecifier","isImportNamespaceSpecifier","isTypeMatch","typeAnnotation","isTSTypeAnnotation","typeReference","isTSTypeReference","typeName","matchedImport","includes","isHOC","hocs","calleePath","isCallExpression","defaultPlaceholder","defaultReactComponentTypes","removeDangerousCode","options","componentTypes","react","Array","isArray","idx","indexOf","splice","traverse","CallExpression","enter","arrowFunctionExpression","nullLiteral","JSXElement","JSXFragment","MemberExpression","state","obj","prop","windowScoped","add","globals","filter","MetaProperty","Identifier","parent","isUnaryExpression","operator","isTSTypeQuery","isClassProperty","key","push","UnaryExpression","arg","type","VariableDeclarator","init","isExpression"],"sources":["../../src/utils/removeDangerousCode.ts"],"sourcesContent":["import type { NodePath } from '@babel/core';\nimport { types as t } from '@babel/core';\nimport type {\n CallExpression,\n Expression,\n Identifier,\n Program,\n V8IntrinsicIdentifier,\n} from '@babel/types';\n\nimport type { CodeRemoverOptions } from '@wyw-in-js/shared';\nimport { nonType } from './findIdentifiers';\nimport { isUnnecessaryReactCall } from './isUnnecessaryReactCall';\nimport { applyAction, removeWithRelated } from './scopeHelpers';\nimport { JSXElementsRemover } from './visitors/JSXElementsRemover';\nimport type { IImport } from './collectExportsAndImports';\nimport { collectExportsAndImports } from './collectExportsAndImports';\n\nconst isGlobal = (id: NodePath<Identifier>): boolean => {\n if (!nonType(id)) {\n return false;\n }\n\n const { scope } = id;\n const { name } = id.node;\n return !scope.hasBinding(name) && scope.hasGlobal(name);\n};\n\nconst ssrCheckFields = new Set([\n 'document',\n 'location',\n 'navigator',\n 'sessionStorage',\n 'localStorage',\n 'window',\n]);\n\nconst forbiddenGlobals = new Set([\n ...ssrCheckFields,\n '$RefreshReg$',\n 'XMLHttpRequest',\n 'clearImmediate',\n 'clearInterval',\n 'clearTimeout',\n 'fetch',\n 'navigator',\n 'setImmediate',\n 'setInterval',\n 'setTimeout',\n]);\n\nconst isBrowserGlobal = (id: NodePath<Identifier>) => {\n return forbiddenGlobals.has(id.node.name) && isGlobal(id);\n};\n\nconst isSSRCheckField = (id: NodePath<Identifier>) => {\n return ssrCheckFields.has(id.node.name) && isGlobal(id);\n};\n\nconst getPropertyName = (path: NodePath): string | null => {\n if (path.isIdentifier()) {\n return path.node.name;\n }\n\n if (path.isStringLiteral()) {\n return path.node.value;\n }\n\n return null;\n};\n\nconst getImport = (path: NodePath): [string, string] | undefined => {\n const programPath = path.findParent((p) => p.isProgram()) as\n | NodePath<Program>\n | undefined;\n if (!programPath) {\n return undefined;\n }\n\n const { imports } = collectExportsAndImports(programPath);\n\n if (path.isIdentifier()) {\n const binding = path.scope.getBinding(path.node.name);\n const matched =\n binding &&\n imports.find(\n (imp): imp is IImport =>\n imp.imported !== 'side-effect' && binding.path.isAncestor(imp.local)\n );\n\n if (matched) {\n return [matched.source, matched.imported];\n }\n }\n\n if (path.isMemberExpression()) {\n const leftPath = path.get('object');\n if (!leftPath.isIdentifier()) {\n // Nested member expression. Not supported yet.\n return undefined;\n }\n\n const rightPath = path.get('property');\n if (!rightPath.isIdentifier()) {\n return undefined;\n }\n\n const binding = path.scope.getBinding(leftPath.node.name);\n const matched =\n binding &&\n imports.find(\n (imp): imp is IImport =>\n imp.imported !== 'side-effect' && binding.path.isAncestor(imp.local)\n );\n\n if (matched) {\n return [matched.source, rightPath.node.name];\n }\n }\n\n return undefined;\n};\n\nconst getTypeImport = (path: NodePath): [string, string] | undefined => {\n // We are looking for either Identifier or TSQualifiedName in path\n if (path.isIdentifier()) {\n const binding = path.scope.getBinding(path.node.name);\n if (!binding) {\n return undefined;\n }\n\n if (\n !binding.path.isImportSpecifier() ||\n !binding.path.parentPath.isImportDeclaration()\n ) {\n return undefined;\n }\n\n const importDeclaration = binding.path.parentPath;\n const imported = binding.path.get('imported');\n const source = importDeclaration.node.source.value;\n const importedNode = imported.node;\n return [\n source,\n t.isIdentifier(importedNode) ? importedNode.name : importedNode.value,\n ];\n }\n\n if (path.isTSQualifiedName()) {\n const leftPath = path.get('left');\n if (!leftPath.isIdentifier()) {\n // Nested type. Not supported yet.\n return undefined;\n }\n\n const rightPath = path.get('right');\n\n const binding = path.scope.getBinding(leftPath.node.name);\n if (!binding) {\n return undefined;\n }\n\n if (\n (!binding.path.isImportDefaultSpecifier() &&\n !binding.path.isImportNamespaceSpecifier()) ||\n !binding.path.parentPath.isImportDeclaration()\n ) {\n return undefined;\n }\n\n return [binding.path.parentPath.node.source.value, rightPath.node.name];\n }\n\n return undefined;\n};\n\nconst isTypeMatch = (\n id: NodePath<Identifier>,\n types: Record<string, string[]>\n): boolean => {\n const typeAnnotation = id.get('typeAnnotation');\n if (!typeAnnotation.isTSTypeAnnotation()) {\n return false;\n }\n\n const typeReference = typeAnnotation.get('typeAnnotation');\n if (!typeReference.isTSTypeReference()) {\n return false;\n }\n\n const typeName = typeReference.get('typeName');\n const matchedImport = getTypeImport(typeName);\n return (\n matchedImport !== undefined &&\n matchedImport[0] in types &&\n types[matchedImport[0]].includes(matchedImport[1])\n );\n};\n\nconst isHOC = (\n path: NodePath<CallExpression>,\n hocs: Record<string, string[]>\n) => {\n let calleePath: NodePath<V8IntrinsicIdentifier | Expression> = path;\n while (calleePath.isCallExpression()) {\n calleePath = calleePath.get('callee');\n }\n\n const matchedImport = getImport(calleePath);\n return (\n matchedImport !== undefined &&\n matchedImport[0] in hocs &&\n hocs[matchedImport[0]].includes(matchedImport[1])\n );\n};\n\nconst defaultPlaceholder = '...';\n\nconst defaultReactComponentTypes = [\n 'ExoticComponent',\n 'FC',\n 'ForwardRefExoticComponent',\n 'FunctionComponent',\n 'LazyExoticComponent',\n 'MemoExoticComponent',\n 'NamedExoticComponent',\n];\n\nexport const removeDangerousCode = (\n programPath: NodePath<Program>,\n options?: CodeRemoverOptions\n) => {\n const hocs = options?.hocs ?? {};\n\n const componentTypes = options?.componentTypes ?? {\n react: [defaultPlaceholder],\n };\n\n if (\n Array.isArray(componentTypes.react) &&\n componentTypes.react.includes(defaultPlaceholder)\n ) {\n const idx = componentTypes.react.indexOf(defaultPlaceholder);\n componentTypes.react = [...componentTypes.react];\n componentTypes.react.splice(idx, 1, ...defaultReactComponentTypes);\n }\n\n programPath.traverse(\n {\n // JSX can be replaced with a dummy value,\n // but we have to do it after we processed template tags.\n CallExpression: {\n enter(p) {\n if (isUnnecessaryReactCall(p)) {\n JSXElementsRemover(p);\n }\n\n if (isHOC(p, hocs)) {\n applyAction([\n 'replace',\n p,\n t.arrowFunctionExpression([], t.nullLiteral()),\n ]);\n }\n },\n },\n JSXElement: {\n enter: JSXElementsRemover,\n },\n JSXFragment: {\n enter: JSXElementsRemover,\n },\n MemberExpression(p, state) {\n const obj = p.get('object');\n const prop = p.get('property');\n if (!obj.isIdentifier({ name: 'window' })) {\n return;\n }\n\n const name = getPropertyName(prop);\n if (!name) {\n return;\n }\n\n state.windowScoped.add(name);\n // eslint-disable-next-line no-param-reassign\n state.globals = state.globals.filter((id) => {\n if (id.node.name === name) {\n removeWithRelated([id]);\n return false;\n }\n\n return true;\n });\n },\n MetaProperty(p) {\n // Remove all references to `import.meta`\n removeWithRelated([p]);\n },\n Identifier(p, state) {\n if (p.find((parent) => parent.isTSTypeReference())) {\n // don't mess with TS type references\n return;\n }\n if (isBrowserGlobal(p)) {\n if (\n p.find(\n (parentPath) =>\n parentPath.isUnaryExpression({ operator: 'typeof' }) ||\n parentPath.isTSTypeQuery()\n )\n ) {\n // Ignore `typeof window` expressions\n return;\n }\n\n if (p.parentPath.isClassProperty()) {\n // ignore class property decls\n return;\n }\n if (p.parentPath.isMemberExpression() && p.key === 'property') {\n // ignore e.g this.fetch()\n // window.fetch will be handled by the windowScoped block below\n return;\n }\n\n removeWithRelated([p]);\n\n return;\n }\n\n if (state.windowScoped.has(p.node.name)) {\n removeWithRelated([p]);\n } else if (isGlobal(p)) {\n state.globals.push(p);\n }\n },\n\n // Since we can use happy-dom, typical SSR checks may not work as expected.\n // We need to detect them and replace with an \"undefined\" literal.\n UnaryExpression(p) {\n if (p.node.operator !== 'typeof') {\n return;\n }\n const arg = p.get('argument');\n if (!arg.isIdentifier() || !isSSRCheckField(arg)) {\n return;\n }\n\n applyAction([\n 'replace',\n p,\n { type: 'StringLiteral', value: 'undefined' },\n ]);\n },\n VariableDeclarator(p) {\n const id = p.get('id');\n const init = p.get('init');\n if (\n id.isIdentifier() &&\n isTypeMatch(id, componentTypes) &&\n init.isExpression()\n ) {\n // Variable is typed as a React component. We can replace its value with a null-function.\n applyAction([\n 'replace',\n init,\n t.arrowFunctionExpression([], t.nullLiteral()),\n ]);\n }\n },\n },\n {\n globals: [] as NodePath<Identifier>[],\n windowScoped: new Set<string>(),\n }\n );\n};\n"],"mappings":"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"}
@@ -1,4 +1,3 @@
1
- import traverse from '@babel/traverse';
2
1
  const caches = new WeakMap();
3
2
  export const getTraversalCache = (path, name) => {
4
3
  const programPath = path.find(p => p.isProgram());
@@ -14,10 +13,6 @@ export const getTraversalCache = (path, name) => {
14
13
  }
15
14
  return cache.get(name);
16
15
  };
17
- const traverseCache = traverse.cache;
18
- export const clearBabelTraversalCache = () => {
19
- traverseCache.clear();
20
- };
21
16
  export const invalidateTraversalCache = path => {
22
17
  const programPath = path.find(p => p.isProgram());
23
18
  if (!programPath) {
@@ -1 +1 @@
1
- {"version":3,"file":"traversalCache.js","names":["traverse","caches","WeakMap","getTraversalCache","path","name","programPath","find","p","isProgram","Error","node","type","has","set","Map","cache","get","traverseCache","clearBabelTraversalCache","clear","invalidateTraversalCache","delete"],"sources":["../../src/utils/traversalCache.ts"],"sourcesContent":["import type { NodePath } from '@babel/traverse';\nimport traverse from '@babel/traverse';\nimport type { Node } from '@babel/types';\n\nconst caches = new WeakMap<\n NodePath,\n Map<string, WeakMap<NodePath | Node, unknown>>\n>();\n\nexport const getTraversalCache = <\n TValue,\n TKey extends NodePath | Node = NodePath,\n>(\n path: NodePath,\n name: string\n) => {\n const programPath = path.find((p) => p.isProgram());\n if (!programPath) {\n throw new Error(`Could not find program for ${path.node.type}`);\n }\n\n if (!caches.has(programPath)) {\n caches.set(programPath, new Map());\n }\n\n const cache = caches.get(programPath)!;\n if (!cache.has(name)) {\n cache.set(name, new WeakMap());\n }\n\n return cache.get(name) as WeakMap<TKey, TValue>;\n};\n\nconst traverseCache = (traverse as unknown as { cache: unknown }).cache;\nexport const clearBabelTraversalCache = () => {\n (traverseCache as { clear: () => void }).clear();\n};\n\nexport const invalidateTraversalCache = (path: NodePath) => {\n const programPath = path.find((p) => p.isProgram());\n if (!programPath) {\n throw new Error(`Could not find program for ${path.node.type}`);\n }\n\n caches.delete(programPath);\n};\n"],"mappings":"AACA,OAAOA,QAAQ,MAAM,iBAAiB;AAGtC,MAAMC,MAAM,GAAG,IAAIC,OAAO,CAGxB,CAAC;AAEH,OAAO,MAAMC,iBAAiB,GAAGA,CAI/BC,IAAc,EACdC,IAAY,KACT;EACH,MAAMC,WAAW,GAAGF,IAAI,CAACG,IAAI,CAAEC,CAAC,IAAKA,CAAC,CAACC,SAAS,CAAC,CAAC,CAAC;EACnD,IAAI,CAACH,WAAW,EAAE;IAChB,MAAM,IAAII,KAAK,CAAE,8BAA6BN,IAAI,CAACO,IAAI,CAACC,IAAK,EAAC,CAAC;EACjE;EAEA,IAAI,CAACX,MAAM,CAACY,GAAG,CAACP,WAAW,CAAC,EAAE;IAC5BL,MAAM,CAACa,GAAG,CAACR,WAAW,EAAE,IAAIS,GAAG,CAAC,CAAC,CAAC;EACpC;EAEA,MAAMC,KAAK,GAAGf,MAAM,CAACgB,GAAG,CAACX,WAAW,CAAE;EACtC,IAAI,CAACU,KAAK,CAACH,GAAG,CAACR,IAAI,CAAC,EAAE;IACpBW,KAAK,CAACF,GAAG,CAACT,IAAI,EAAE,IAAIH,OAAO,CAAC,CAAC,CAAC;EAChC;EAEA,OAAOc,KAAK,CAACC,GAAG,CAACZ,IAAI,CAAC;AACxB,CAAC;AAED,MAAMa,aAAa,GAAIlB,QAAQ,CAAmCgB,KAAK;AACvE,OAAO,MAAMG,wBAAwB,GAAGA,CAAA,KAAM;EAC3CD,aAAa,CAA2BE,KAAK,CAAC,CAAC;AAClD,CAAC;AAED,OAAO,MAAMC,wBAAwB,GAAIjB,IAAc,IAAK;EAC1D,MAAME,WAAW,GAAGF,IAAI,CAACG,IAAI,CAAEC,CAAC,IAAKA,CAAC,CAACC,SAAS,CAAC,CAAC,CAAC;EACnD,IAAI,CAACH,WAAW,EAAE;IAChB,MAAM,IAAII,KAAK,CAAE,8BAA6BN,IAAI,CAACO,IAAI,CAACC,IAAK,EAAC,CAAC;EACjE;EAEAX,MAAM,CAACqB,MAAM,CAAChB,WAAW,CAAC;AAC5B,CAAC"}
1
+ {"version":3,"file":"traversalCache.js","names":["caches","WeakMap","getTraversalCache","path","name","programPath","find","p","isProgram","Error","node","type","has","set","Map","cache","get","invalidateTraversalCache","delete"],"sources":["../../src/utils/traversalCache.ts"],"sourcesContent":["import type { NodePath } from '@babel/traverse';\nimport type { Node } from '@babel/types';\n\nconst caches = new WeakMap<\n NodePath,\n Map<string, WeakMap<NodePath | Node, unknown>>\n>();\n\nexport const getTraversalCache = <\n TValue,\n TKey extends NodePath | Node = NodePath,\n>(\n path: NodePath,\n name: string\n) => {\n const programPath = path.find((p) => p.isProgram());\n if (!programPath) {\n throw new Error(`Could not find program for ${path.node.type}`);\n }\n\n if (!caches.has(programPath)) {\n caches.set(programPath, new Map());\n }\n\n const cache = caches.get(programPath)!;\n if (!cache.has(name)) {\n cache.set(name, new WeakMap());\n }\n\n return cache.get(name) as WeakMap<TKey, TValue>;\n};\n\nexport const invalidateTraversalCache = (path: NodePath) => {\n const programPath = path.find((p) => p.isProgram());\n if (!programPath) {\n throw new Error(`Could not find program for ${path.node.type}`);\n }\n\n caches.delete(programPath);\n};\n"],"mappings":"AAGA,MAAMA,MAAM,GAAG,IAAIC,OAAO,CAGxB,CAAC;AAEH,OAAO,MAAMC,iBAAiB,GAAGA,CAI/BC,IAAc,EACdC,IAAY,KACT;EACH,MAAMC,WAAW,GAAGF,IAAI,CAACG,IAAI,CAAEC,CAAC,IAAKA,CAAC,CAACC,SAAS,CAAC,CAAC,CAAC;EACnD,IAAI,CAACH,WAAW,EAAE;IAChB,MAAM,IAAII,KAAK,CAAE,8BAA6BN,IAAI,CAACO,IAAI,CAACC,IAAK,EAAC,CAAC;EACjE;EAEA,IAAI,CAACX,MAAM,CAACY,GAAG,CAACP,WAAW,CAAC,EAAE;IAC5BL,MAAM,CAACa,GAAG,CAACR,WAAW,EAAE,IAAIS,GAAG,CAAC,CAAC,CAAC;EACpC;EAEA,MAAMC,KAAK,GAAGf,MAAM,CAACgB,GAAG,CAACX,WAAW,CAAE;EACtC,IAAI,CAACU,KAAK,CAACH,GAAG,CAACR,IAAI,CAAC,EAAE;IACpBW,KAAK,CAACF,GAAG,CAACT,IAAI,EAAE,IAAIH,OAAO,CAAC,CAAC,CAAC;EAChC;EAEA,OAAOc,KAAK,CAACC,GAAG,CAACZ,IAAI,CAAC;AACxB,CAAC;AAED,OAAO,MAAMa,wBAAwB,GAAId,IAAc,IAAK;EAC1D,MAAME,WAAW,GAAGF,IAAI,CAACG,IAAI,CAAEC,CAAC,IAAKA,CAAC,CAACC,SAAS,CAAC,CAAC,CAAC;EACnD,IAAI,CAACH,WAAW,EAAE;IAChB,MAAM,IAAII,KAAK,CAAE,8BAA6BN,IAAI,CAACO,IAAI,CAACC,IAAK,EAAC,CAAC;EACjE;EAEAX,MAAM,CAACkB,MAAM,CAACb,WAAW,CAAC;AAC5B,CAAC"}
@@ -15,14 +15,25 @@ function createWindow() {
15
15
  win.Uint8Array = Uint8Array;
16
16
  return win;
17
17
  }
18
+
19
+ /**
20
+ * `happy-dom` already has required references, so we don't need to set them.
21
+ */
22
+ function setReferencePropertyIfNotPresent(context, key) {
23
+ if (context[key] === context) {
24
+ return;
25
+ }
26
+ context[key] = context;
27
+ }
18
28
  function createBaseContext(win, additionalContext) {
19
29
  const baseContext = win ?? {};
30
+ setReferencePropertyIfNotPresent(baseContext, 'window');
31
+ setReferencePropertyIfNotPresent(baseContext, 'self');
32
+ setReferencePropertyIfNotPresent(baseContext, 'top');
33
+ setReferencePropertyIfNotPresent(baseContext, 'parent');
34
+ setReferencePropertyIfNotPresent(baseContext, 'global');
35
+ setReferencePropertyIfNotPresent(baseContext, 'process');
20
36
  baseContext.document = win?.document;
21
- baseContext.window = win;
22
- baseContext.self = win;
23
- baseContext.top = win;
24
- baseContext.parent = win;
25
- baseContext.global = win;
26
37
  baseContext.process = process;
27
38
  baseContext.clearImmediate = NOOP;
28
39
  baseContext.clearInterval = NOOP;
@@ -42,7 +53,7 @@ function createHappyDOMWindow() {
42
53
  const win = createWindow();
43
54
  return {
44
55
  teardown: () => {
45
- win.happyDOM.cancelAsync();
56
+ win.happyDOM.abort();
46
57
  },
47
58
  window: win
48
59
  };
@@ -1 +1 @@
1
- {"version":3,"file":"createVmContext.js","names":["vm","isFeatureEnabled","process","NOOP","createWindow","Window","GlobalWindow","require","HappyWindow","win","Buffer","Uint8Array","createBaseContext","additionalContext","baseContext","document","window","self","top","parent","global","clearImmediate","clearInterval","clearTimeout","setImmediate","requestAnimationFrame","setInterval","setTimeout","key","createHappyDOMWindow","teardown","happyDOM","cancelAsync","createNothing","undefined","createVmContext","filename","features","overrideContext","i","isHappyDOMEnabled","__filename","context","createContext"],"sources":["../../src/vm/createVmContext.ts"],"sourcesContent":["import * as vm from 'vm';\n\nimport type { Window } from 'happy-dom';\n\nimport type { FeatureFlags, StrictOptions } from '@wyw-in-js/shared';\nimport { isFeatureEnabled } from '@wyw-in-js/shared';\n\nimport * as process from './process';\n\nconst NOOP = () => {};\n\nfunction createWindow(): Window {\n const { Window, GlobalWindow } = require('happy-dom');\n const HappyWindow = GlobalWindow || Window;\n const win = new HappyWindow();\n\n // TODO: browser doesn't expose Buffer, but a lot of dependencies use it\n win.Buffer = Buffer;\n win.Uint8Array = Uint8Array;\n\n return win;\n}\n\nfunction createBaseContext(\n win: Window | undefined,\n additionalContext: Partial<vm.Context>\n): Partial<vm.Context> {\n const baseContext: vm.Context = win ?? {};\n\n baseContext.document = win?.document;\n baseContext.window = win;\n baseContext.self = win;\n baseContext.top = win;\n baseContext.parent = win;\n baseContext.global = win;\n\n baseContext.process = process;\n\n baseContext.clearImmediate = NOOP;\n baseContext.clearInterval = NOOP;\n baseContext.clearTimeout = NOOP;\n baseContext.setImmediate = NOOP;\n baseContext.requestAnimationFrame = NOOP;\n baseContext.setInterval = NOOP;\n baseContext.setTimeout = NOOP;\n\n // eslint-disable-next-line guard-for-in,no-restricted-syntax\n for (const key in additionalContext) {\n baseContext[key] = additionalContext[key];\n }\n\n return baseContext;\n}\n\nfunction createHappyDOMWindow() {\n const win = createWindow();\n\n return {\n teardown: () => {\n win.happyDOM.cancelAsync();\n },\n window: win,\n };\n}\n\nfunction createNothing() {\n return {\n teardown: () => {},\n window: undefined,\n };\n}\n\nexport function createVmContext(\n filename: string,\n features: FeatureFlags<'happyDOM'>,\n additionalContext: Partial<vm.Context>,\n overrideContext: StrictOptions['overrideContext'] = (i) => i\n) {\n const isHappyDOMEnabled = isFeatureEnabled(features, 'happyDOM', filename);\n\n const { teardown, window } = isHappyDOMEnabled\n ? createHappyDOMWindow()\n : createNothing();\n const baseContext = createBaseContext(\n window,\n overrideContext(\n {\n __filename: filename,\n ...additionalContext,\n },\n filename\n )\n );\n\n const context = vm.createContext(baseContext);\n\n return {\n context,\n teardown,\n };\n}\n"],"mappings":"AAAA,OAAO,KAAKA,EAAE,MAAM,IAAI;AAKxB,SAASC,gBAAgB,QAAQ,mBAAmB;AAEpD,OAAO,KAAKC,OAAO,MAAM,WAAW;AAEpC,MAAMC,IAAI,GAAGA,CAAA,KAAM,CAAC,CAAC;AAErB,SAASC,YAAYA,CAAA,EAAW;EAC9B,MAAM;IAAEC,MAAM;IAAEC;EAAa,CAAC,GAAGC,OAAO,CAAC,WAAW,CAAC;EACrD,MAAMC,WAAW,GAAGF,YAAY,IAAID,MAAM;EAC1C,MAAMI,GAAG,GAAG,IAAID,WAAW,CAAC,CAAC;;EAE7B;EACAC,GAAG,CAACC,MAAM,GAAGA,MAAM;EACnBD,GAAG,CAACE,UAAU,GAAGA,UAAU;EAE3B,OAAOF,GAAG;AACZ;AAEA,SAASG,iBAAiBA,CACxBH,GAAuB,EACvBI,iBAAsC,EACjB;EACrB,MAAMC,WAAuB,GAAGL,GAAG,IAAI,CAAC,CAAC;EAEzCK,WAAW,CAACC,QAAQ,GAAGN,GAAG,EAAEM,QAAQ;EACpCD,WAAW,CAACE,MAAM,GAAGP,GAAG;EACxBK,WAAW,CAACG,IAAI,GAAGR,GAAG;EACtBK,WAAW,CAACI,GAAG,GAAGT,GAAG;EACrBK,WAAW,CAACK,MAAM,GAAGV,GAAG;EACxBK,WAAW,CAACM,MAAM,GAAGX,GAAG;EAExBK,WAAW,CAACZ,OAAO,GAAGA,OAAO;EAE7BY,WAAW,CAACO,cAAc,GAAGlB,IAAI;EACjCW,WAAW,CAACQ,aAAa,GAAGnB,IAAI;EAChCW,WAAW,CAACS,YAAY,GAAGpB,IAAI;EAC/BW,WAAW,CAACU,YAAY,GAAGrB,IAAI;EAC/BW,WAAW,CAACW,qBAAqB,GAAGtB,IAAI;EACxCW,WAAW,CAACY,WAAW,GAAGvB,IAAI;EAC9BW,WAAW,CAACa,UAAU,GAAGxB,IAAI;;EAE7B;EACA,KAAK,MAAMyB,GAAG,IAAIf,iBAAiB,EAAE;IACnCC,WAAW,CAACc,GAAG,CAAC,GAAGf,iBAAiB,CAACe,GAAG,CAAC;EAC3C;EAEA,OAAOd,WAAW;AACpB;AAEA,SAASe,oBAAoBA,CAAA,EAAG;EAC9B,MAAMpB,GAAG,GAAGL,YAAY,CAAC,CAAC;EAE1B,OAAO;IACL0B,QAAQ,EAAEA,CAAA,KAAM;MACdrB,GAAG,CAACsB,QAAQ,CAACC,WAAW,CAAC,CAAC;IAC5B,CAAC;IACDhB,MAAM,EAAEP;EACV,CAAC;AACH;AAEA,SAASwB,aAAaA,CAAA,EAAG;EACvB,OAAO;IACLH,QAAQ,EAAEA,CAAA,KAAM,CAAC,CAAC;IAClBd,MAAM,EAAEkB;EACV,CAAC;AACH;AAEA,OAAO,SAASC,eAAeA,CAC7BC,QAAgB,EAChBC,QAAkC,EAClCxB,iBAAsC,EACtCyB,eAAiD,GAAIC,CAAC,IAAKA,CAAC,EAC5D;EACA,MAAMC,iBAAiB,GAAGvC,gBAAgB,CAACoC,QAAQ,EAAE,UAAU,EAAED,QAAQ,CAAC;EAE1E,MAAM;IAAEN,QAAQ;IAAEd;EAAO,CAAC,GAAGwB,iBAAiB,GAC1CX,oBAAoB,CAAC,CAAC,GACtBI,aAAa,CAAC,CAAC;EACnB,MAAMnB,WAAW,GAAGF,iBAAiB,CACnCI,MAAM,EACNsB,eAAe,CACb;IACEG,UAAU,EAAEL,QAAQ;IACpB,GAAGvB;EACL,CAAC,EACDuB,QACF,CACF,CAAC;EAED,MAAMM,OAAO,GAAG1C,EAAE,CAAC2C,aAAa,CAAC7B,WAAW,CAAC;EAE7C,OAAO;IACL4B,OAAO;IACPZ;EACF,CAAC;AACH"}
1
+ {"version":3,"file":"createVmContext.js","names":["vm","isFeatureEnabled","process","NOOP","createWindow","Window","GlobalWindow","require","HappyWindow","win","Buffer","Uint8Array","setReferencePropertyIfNotPresent","context","key","createBaseContext","additionalContext","baseContext","document","clearImmediate","clearInterval","clearTimeout","setImmediate","requestAnimationFrame","setInterval","setTimeout","createHappyDOMWindow","teardown","happyDOM","abort","window","createNothing","undefined","createVmContext","filename","features","overrideContext","i","isHappyDOMEnabled","__filename","createContext"],"sources":["../../src/vm/createVmContext.ts"],"sourcesContent":["import * as vm from 'vm';\n\nimport type { Window } from 'happy-dom';\n\nimport type { FeatureFlags, StrictOptions } from '@wyw-in-js/shared';\nimport { isFeatureEnabled } from '@wyw-in-js/shared';\n\nimport * as process from './process';\n\nconst NOOP = () => {};\n\nfunction createWindow(): Window {\n const { Window, GlobalWindow } = require('happy-dom');\n const HappyWindow = GlobalWindow || Window;\n const win = new HappyWindow();\n\n // TODO: browser doesn't expose Buffer, but a lot of dependencies use it\n win.Buffer = Buffer;\n win.Uint8Array = Uint8Array;\n\n return win;\n}\n\n/**\n * `happy-dom` already has required references, so we don't need to set them.\n */\nfunction setReferencePropertyIfNotPresent(\n context: vm.Context,\n key: string\n): void {\n if (context[key] === context) {\n return;\n }\n\n context[key] = context;\n}\n\nfunction createBaseContext(\n win: Window | undefined,\n additionalContext: Partial<vm.Context>\n): Partial<vm.Context> {\n const baseContext: vm.Context = win ?? {};\n\n setReferencePropertyIfNotPresent(baseContext, 'window');\n setReferencePropertyIfNotPresent(baseContext, 'self');\n setReferencePropertyIfNotPresent(baseContext, 'top');\n setReferencePropertyIfNotPresent(baseContext, 'parent');\n setReferencePropertyIfNotPresent(baseContext, 'global');\n setReferencePropertyIfNotPresent(baseContext, 'process');\n\n baseContext.document = win?.document;\n baseContext.process = process;\n\n baseContext.clearImmediate = NOOP;\n baseContext.clearInterval = NOOP;\n baseContext.clearTimeout = NOOP;\n baseContext.setImmediate = NOOP;\n baseContext.requestAnimationFrame = NOOP;\n baseContext.setInterval = NOOP;\n baseContext.setTimeout = NOOP;\n\n // eslint-disable-next-line guard-for-in,no-restricted-syntax\n for (const key in additionalContext) {\n baseContext[key] = additionalContext[key];\n }\n\n return baseContext;\n}\n\nfunction createHappyDOMWindow() {\n const win = createWindow();\n\n return {\n teardown: () => {\n win.happyDOM.abort();\n },\n window: win,\n };\n}\n\nfunction createNothing() {\n return {\n teardown: () => {},\n window: undefined,\n };\n}\n\nexport function createVmContext(\n filename: string,\n features: FeatureFlags<'happyDOM'>,\n additionalContext: Partial<vm.Context>,\n overrideContext: StrictOptions['overrideContext'] = (i) => i\n) {\n const isHappyDOMEnabled = isFeatureEnabled(features, 'happyDOM', filename);\n\n const { teardown, window } = isHappyDOMEnabled\n ? createHappyDOMWindow()\n : createNothing();\n const baseContext = createBaseContext(\n window,\n overrideContext(\n {\n __filename: filename,\n ...additionalContext,\n },\n filename\n )\n );\n\n const context = vm.createContext(baseContext);\n\n return {\n context,\n teardown,\n };\n}\n"],"mappings":"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"}
@@ -25,7 +25,12 @@ function dynamicImport(babel) {
25
25
  path.replaceWith(t.callExpression(t.identifier('__wyw_dynamic_import'), [t.cloneNode(moduleName.node, true, true)]));
26
26
  return;
27
27
  }
28
- throw new Error('Dynamic import argument must be a string or a template literal');
28
+
29
+ // Throw an error if this import will be reached during evaluation
30
+ // throw new Error(
31
+ // 'Dynamic import argument must be a string or a template literal'
32
+ // );
33
+ path.replaceWith(t.callExpression(t.arrowFunctionExpression([], t.blockStatement([t.throwStatement(t.newExpression(t.identifier('Error'), [t.stringLiteral('Dynamic import argument must be a string or a template literal')]))])), []));
29
34
  }
30
35
  }
31
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"dynamic-import.js","names":["dynamicImport","babel","types","t","name","visitor","CallExpression","path","get","isImport","moduleName","isStringLiteral","replaceWith","callExpression","identifier","stringLiteral","node","value","isTemplateLiteral","cloneNode","Error"],"sources":["../../src/plugins/dynamic-import.ts"],"sourcesContent":["import type { NodePath, PluginObj } from '@babel/core';\n\nimport type { Core } from '../babel';\n\n/**\n * The plugin that replaces `import()` with `__wyw_dynamic_import` as Node VM does not support dynamic imports yet.\n */\nexport default function dynamicImport(babel: Core): PluginObj {\n const { types: t } = babel;\n\n return {\n name: '@wyw-in-js/transform/dynamic-import',\n visitor: {\n CallExpression(path) {\n if (path.get('callee').isImport()) {\n const moduleName = path.get('arguments.0') as NodePath;\n\n if (moduleName.isStringLiteral()) {\n path.replaceWith(\n t.callExpression(t.identifier('__wyw_dynamic_import'), [\n t.stringLiteral(moduleName.node.value),\n ])\n );\n return;\n }\n\n if (moduleName.isTemplateLiteral()) {\n path.replaceWith(\n t.callExpression(t.identifier('__wyw_dynamic_import'), [\n t.cloneNode(moduleName.node, true, true),\n ])\n );\n return;\n }\n\n throw new Error(\n 'Dynamic import argument must be a string or a template literal'\n );\n }\n },\n },\n };\n}\n"],"mappings":";;;;;;AAIA;AACA;AACA;AACe,SAASA,aAAaA,CAACC,KAAW,EAAa;EAC5D,MAAM;IAAEC,KAAK,EAAEC;EAAE,CAAC,GAAGF,KAAK;EAE1B,OAAO;IACLG,IAAI,EAAE,qCAAqC;IAC3CC,OAAO,EAAE;MACPC,cAAcA,CAACC,IAAI,EAAE;QACnB,IAAIA,IAAI,CAACC,GAAG,CAAC,QAAQ,CAAC,CAACC,QAAQ,CAAC,CAAC,EAAE;UACjC,MAAMC,UAAU,GAAGH,IAAI,CAACC,GAAG,CAAC,aAAa,CAAa;UAEtD,IAAIE,UAAU,CAACC,eAAe,CAAC,CAAC,EAAE;YAChCJ,IAAI,CAACK,WAAW,CACdT,CAAC,CAACU,cAAc,CAACV,CAAC,CAACW,UAAU,CAAC,sBAAsB,CAAC,EAAE,CACrDX,CAAC,CAACY,aAAa,CAACL,UAAU,CAACM,IAAI,CAACC,KAAK,CAAC,CACvC,CACH,CAAC;YACD;UACF;UAEA,IAAIP,UAAU,CAACQ,iBAAiB,CAAC,CAAC,EAAE;YAClCX,IAAI,CAACK,WAAW,CACdT,CAAC,CAACU,cAAc,CAACV,CAAC,CAACW,UAAU,CAAC,sBAAsB,CAAC,EAAE,CACrDX,CAAC,CAACgB,SAAS,CAACT,UAAU,CAACM,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CACzC,CACH,CAAC;YACD;UACF;UAEA,MAAM,IAAII,KAAK,CACb,gEACF,CAAC;QACH;MACF;IACF;EACF,CAAC;AACH"}
1
+ {"version":3,"file":"dynamic-import.js","names":["dynamicImport","babel","types","t","name","visitor","CallExpression","path","get","isImport","moduleName","isStringLiteral","replaceWith","callExpression","identifier","stringLiteral","node","value","isTemplateLiteral","cloneNode","arrowFunctionExpression","blockStatement","throwStatement","newExpression"],"sources":["../../src/plugins/dynamic-import.ts"],"sourcesContent":["import type { NodePath, PluginObj } from '@babel/core';\n\nimport type { Core } from '../babel';\n\n/**\n * The plugin that replaces `import()` with `__wyw_dynamic_import` as Node VM does not support dynamic imports yet.\n */\nexport default function dynamicImport(babel: Core): PluginObj {\n const { types: t } = babel;\n\n return {\n name: '@wyw-in-js/transform/dynamic-import',\n visitor: {\n CallExpression(path) {\n if (path.get('callee').isImport()) {\n const moduleName = path.get('arguments.0') as NodePath;\n\n if (moduleName.isStringLiteral()) {\n path.replaceWith(\n t.callExpression(t.identifier('__wyw_dynamic_import'), [\n t.stringLiteral(moduleName.node.value),\n ])\n );\n return;\n }\n\n if (moduleName.isTemplateLiteral()) {\n path.replaceWith(\n t.callExpression(t.identifier('__wyw_dynamic_import'), [\n t.cloneNode(moduleName.node, true, true),\n ])\n );\n return;\n }\n\n // Throw an error if this import will be reached during evaluation\n // throw new Error(\n // 'Dynamic import argument must be a string or a template literal'\n // );\n path.replaceWith(\n t.callExpression(\n t.arrowFunctionExpression(\n [],\n t.blockStatement([\n t.throwStatement(\n t.newExpression(t.identifier('Error'), [\n t.stringLiteral(\n 'Dynamic import argument must be a string or a template literal'\n ),\n ])\n ),\n ])\n ),\n []\n )\n );\n }\n },\n },\n };\n}\n"],"mappings":";;;;;;AAIA;AACA;AACA;AACe,SAASA,aAAaA,CAACC,KAAW,EAAa;EAC5D,MAAM;IAAEC,KAAK,EAAEC;EAAE,CAAC,GAAGF,KAAK;EAE1B,OAAO;IACLG,IAAI,EAAE,qCAAqC;IAC3CC,OAAO,EAAE;MACPC,cAAcA,CAACC,IAAI,EAAE;QACnB,IAAIA,IAAI,CAACC,GAAG,CAAC,QAAQ,CAAC,CAACC,QAAQ,CAAC,CAAC,EAAE;UACjC,MAAMC,UAAU,GAAGH,IAAI,CAACC,GAAG,CAAC,aAAa,CAAa;UAEtD,IAAIE,UAAU,CAACC,eAAe,CAAC,CAAC,EAAE;YAChCJ,IAAI,CAACK,WAAW,CACdT,CAAC,CAACU,cAAc,CAACV,CAAC,CAACW,UAAU,CAAC,sBAAsB,CAAC,EAAE,CACrDX,CAAC,CAACY,aAAa,CAACL,UAAU,CAACM,IAAI,CAACC,KAAK,CAAC,CACvC,CACH,CAAC;YACD;UACF;UAEA,IAAIP,UAAU,CAACQ,iBAAiB,CAAC,CAAC,EAAE;YAClCX,IAAI,CAACK,WAAW,CACdT,CAAC,CAACU,cAAc,CAACV,CAAC,CAACW,UAAU,CAAC,sBAAsB,CAAC,EAAE,CACrDX,CAAC,CAACgB,SAAS,CAACT,UAAU,CAACM,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CACzC,CACH,CAAC;YACD;UACF;;UAEA;UACA;UACA;UACA;UACAT,IAAI,CAACK,WAAW,CACdT,CAAC,CAACU,cAAc,CACdV,CAAC,CAACiB,uBAAuB,CACvB,EAAE,EACFjB,CAAC,CAACkB,cAAc,CAAC,CACflB,CAAC,CAACmB,cAAc,CACdnB,CAAC,CAACoB,aAAa,CAACpB,CAAC,CAACW,UAAU,CAAC,OAAO,CAAC,EAAE,CACrCX,CAAC,CAACY,aAAa,CACb,gEACF,CAAC,CACF,CACH,CAAC,CACF,CACH,CAAC,EACD,EACF,CACF,CAAC;QACH;MACF;IACF;EACF,CAAC;AACH"}
@@ -44,7 +44,7 @@ function preeval(babel, options) {
44
44
  });
45
45
  if ((0, _shared.isFeatureEnabled)(options.features, 'dangerousCodeRemover', filename)) {
46
46
  log('start', 'Strip all JSX and browser related stuff');
47
- eventEmitter.perf('transform:preeval:removeDangerousCode', () => (0, _removeDangerousCode.removeDangerousCode)(file.path));
47
+ eventEmitter.perf('transform:preeval:removeDangerousCode', () => (0, _removeDangerousCode.removeDangerousCode)(file.path, options.codeRemover));
48
48
  }
49
49
  },
50
50
  visitor: {},
@@ -1 +1 @@
1
- {"version":3,"file":"preeval.js","names":["_shared","require","_getTagProcessor","_EventEmitter","_addIdentifierToWywPreval","_getFileIdx","_removeDangerousCode","_traversalCache","preeval","babel","options","_options$eventEmitter","types","t","eventEmitter","EventEmitter","dummy","name","pre","file","filename","opts","log","logger","extend","getFileIdx","rootScope","scope","processors","perf","applyProcessors","path","processor","dependencies","forEach","dependency","ex","type","addIdentifierToWywPreval","doEvaltimeReplacement","push","isFeatureEnabled","features","removeDangerousCode","visitor","post","invalidateTraversalCache","length","metadata","wywInJS","replacements","rules","wywPreval","getData","wywExport","expressionStatement","assignmentExpression","memberExpression","identifier","objectExpression","pushContainer","_default","exports","default"],"sources":["../../src/plugins/preeval.ts"],"sourcesContent":["/**\n * This file is a babel preset used to transform files inside evaluators.\n * It works the same as main `babel/extract` preset, but do not evaluate lazy dependencies.\n */\nimport type { BabelFile, PluginObj } from '@babel/core';\n\nimport type { StrictOptions } from '@wyw-in-js/shared';\nimport { isFeatureEnabled, logger } from '@wyw-in-js/shared';\n\nimport { applyProcessors } from '../utils/getTagProcessor';\nimport type { Core } from '../babel';\nimport type { IPluginState } from '../types';\nimport { EventEmitter } from '../utils/EventEmitter';\nimport { addIdentifierToWywPreval } from '../utils/addIdentifierToWywPreval';\nimport { getFileIdx } from '../utils/getFileIdx';\nimport { removeDangerousCode } from '../utils/removeDangerousCode';\nimport { invalidateTraversalCache } from '../utils/traversalCache';\n\nexport type PreevalOptions = Pick<\n StrictOptions,\n | 'classNameSlug'\n | 'displayName'\n | 'extensions'\n | 'evaluate'\n | 'features'\n | 'tagResolver'\n> & { eventEmitter?: EventEmitter };\n\nexport function preeval(\n babel: Core,\n options: PreevalOptions\n): PluginObj<IPluginState & { onFinish: () => void }> {\n const { types: t } = babel;\n const eventEmitter = options.eventEmitter ?? EventEmitter.dummy;\n return {\n name: '@wyw-in-js/transform/preeval',\n pre(file: BabelFile) {\n const filename = file.opts.filename!;\n const log = logger.extend('preeval').extend(getFileIdx(filename));\n\n log('start', 'Looking for template literals…');\n\n const rootScope = file.scope;\n this.processors = [];\n\n eventEmitter.perf('transform:preeval:processTemplate', () => {\n applyProcessors(file.path, file.opts, options, (processor) => {\n processor.dependencies.forEach((dependency) => {\n if (dependency.ex.type === 'Identifier') {\n addIdentifierToWywPreval(rootScope, dependency.ex.name);\n }\n });\n\n processor.doEvaltimeReplacement();\n this.processors.push(processor);\n });\n });\n\n if (\n isFeatureEnabled(options.features, 'dangerousCodeRemover', filename)\n ) {\n log('start', 'Strip all JSX and browser related stuff');\n eventEmitter.perf('transform:preeval:removeDangerousCode', () =>\n removeDangerousCode(file.path)\n );\n }\n },\n visitor: {},\n post(file: BabelFile) {\n const log = logger\n .extend('preeval')\n .extend(getFileIdx(file.opts.filename!));\n\n invalidateTraversalCache(file.path);\n\n if (this.processors.length === 0) {\n log('end', \"We didn't find any wyw-in-js template literals\");\n\n // We didn't find any wyw-in-js template literals.\n return;\n }\n\n this.file.metadata.wywInJS = {\n processors: this.processors,\n replacements: [],\n rules: {},\n dependencies: [],\n };\n\n const wywPreval = file.path.getData('__wywPreval');\n if (!wywPreval) {\n // Event if there is no dependencies, we still need to add __wywPreval\n const wywExport = t.expressionStatement(\n t.assignmentExpression(\n '=',\n t.memberExpression(\n t.identifier('exports'),\n t.identifier('__wywPreval')\n ),\n t.objectExpression([])\n )\n );\n\n file.path.pushContainer('body', wywExport);\n }\n\n log('end', '__wywPreval has been added');\n },\n };\n}\n\nexport default preeval;\n"],"mappings":"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"}
1
+ {"version":3,"file":"preeval.js","names":["_shared","require","_getTagProcessor","_EventEmitter","_addIdentifierToWywPreval","_getFileIdx","_removeDangerousCode","_traversalCache","preeval","babel","options","_options$eventEmitter","types","t","eventEmitter","EventEmitter","dummy","name","pre","file","filename","opts","log","logger","extend","getFileIdx","rootScope","scope","processors","perf","applyProcessors","path","processor","dependencies","forEach","dependency","ex","type","addIdentifierToWywPreval","doEvaltimeReplacement","push","isFeatureEnabled","features","removeDangerousCode","codeRemover","visitor","post","invalidateTraversalCache","length","metadata","wywInJS","replacements","rules","wywPreval","getData","wywExport","expressionStatement","assignmentExpression","memberExpression","identifier","objectExpression","pushContainer","_default","exports","default"],"sources":["../../src/plugins/preeval.ts"],"sourcesContent":["/**\n * This file is a babel preset used to transform files inside evaluators.\n * It works the same as main `babel/extract` preset, but do not evaluate lazy dependencies.\n */\nimport type { BabelFile, PluginObj } from '@babel/core';\n\nimport type { StrictOptions } from '@wyw-in-js/shared';\nimport { isFeatureEnabled, logger } from '@wyw-in-js/shared';\n\nimport { applyProcessors } from '../utils/getTagProcessor';\nimport type { Core } from '../babel';\nimport type { IPluginState } from '../types';\nimport { EventEmitter } from '../utils/EventEmitter';\nimport { addIdentifierToWywPreval } from '../utils/addIdentifierToWywPreval';\nimport { getFileIdx } from '../utils/getFileIdx';\nimport { removeDangerousCode } from '../utils/removeDangerousCode';\nimport { invalidateTraversalCache } from '../utils/traversalCache';\n\nexport type PreevalOptions = Pick<\n StrictOptions,\n | 'classNameSlug'\n | 'codeRemover'\n | 'displayName'\n | 'extensions'\n | 'evaluate'\n | 'features'\n | 'tagResolver'\n> & { eventEmitter?: EventEmitter };\n\nexport function preeval(\n babel: Core,\n options: PreevalOptions\n): PluginObj<IPluginState & { onFinish: () => void }> {\n const { types: t } = babel;\n const eventEmitter = options.eventEmitter ?? EventEmitter.dummy;\n return {\n name: '@wyw-in-js/transform/preeval',\n pre(file: BabelFile) {\n const filename = file.opts.filename!;\n const log = logger.extend('preeval').extend(getFileIdx(filename));\n\n log('start', 'Looking for template literals…');\n\n const rootScope = file.scope;\n this.processors = [];\n\n eventEmitter.perf('transform:preeval:processTemplate', () => {\n applyProcessors(file.path, file.opts, options, (processor) => {\n processor.dependencies.forEach((dependency) => {\n if (dependency.ex.type === 'Identifier') {\n addIdentifierToWywPreval(rootScope, dependency.ex.name);\n }\n });\n\n processor.doEvaltimeReplacement();\n this.processors.push(processor);\n });\n });\n\n if (\n isFeatureEnabled(options.features, 'dangerousCodeRemover', filename)\n ) {\n log('start', 'Strip all JSX and browser related stuff');\n eventEmitter.perf('transform:preeval:removeDangerousCode', () =>\n removeDangerousCode(file.path, options.codeRemover)\n );\n }\n },\n visitor: {},\n post(file: BabelFile) {\n const log = logger\n .extend('preeval')\n .extend(getFileIdx(file.opts.filename!));\n\n invalidateTraversalCache(file.path);\n\n if (this.processors.length === 0) {\n log('end', \"We didn't find any wyw-in-js template literals\");\n\n // We didn't find any wyw-in-js template literals.\n return;\n }\n\n this.file.metadata.wywInJS = {\n processors: this.processors,\n replacements: [],\n rules: {},\n dependencies: [],\n };\n\n const wywPreval = file.path.getData('__wywPreval');\n if (!wywPreval) {\n // Event if there is no dependencies, we still need to add __wywPreval\n const wywExport = t.expressionStatement(\n t.assignmentExpression(\n '=',\n t.memberExpression(\n t.identifier('exports'),\n t.identifier('__wywPreval')\n ),\n t.objectExpression([])\n )\n );\n\n file.path.pushContainer('body', wywExport);\n }\n\n log('end', '__wywPreval has been added');\n },\n };\n}\n\nexport default preeval;\n"],"mappings":"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"}
@@ -4,10 +4,12 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.removeDangerousCode = void 0;
7
+ var _core = require("@babel/core");
7
8
  var _findIdentifiers = require("./findIdentifiers");
8
9
  var _isUnnecessaryReactCall = require("./isUnnecessaryReactCall");
9
10
  var _scopeHelpers = require("./scopeHelpers");
10
11
  var _JSXElementsRemover = require("./visitors/JSXElementsRemover");
12
+ var _collectExportsAndImports = require("./collectExportsAndImports");
11
13
  const isGlobal = id => {
12
14
  if (!(0, _findIdentifiers.nonType)(id)) {
13
15
  return false;
@@ -37,7 +39,107 @@ const getPropertyName = path => {
37
39
  }
38
40
  return null;
39
41
  };
40
- const removeDangerousCode = programPath => {
42
+ const getImport = path => {
43
+ const programPath = path.findParent(p => p.isProgram());
44
+ if (!programPath) {
45
+ return undefined;
46
+ }
47
+ const {
48
+ imports
49
+ } = (0, _collectExportsAndImports.collectExportsAndImports)(programPath);
50
+ if (path.isIdentifier()) {
51
+ const binding = path.scope.getBinding(path.node.name);
52
+ const matched = binding && imports.find(imp => imp.imported !== 'side-effect' && binding.path.isAncestor(imp.local));
53
+ if (matched) {
54
+ return [matched.source, matched.imported];
55
+ }
56
+ }
57
+ if (path.isMemberExpression()) {
58
+ const leftPath = path.get('object');
59
+ if (!leftPath.isIdentifier()) {
60
+ // Nested member expression. Not supported yet.
61
+ return undefined;
62
+ }
63
+ const rightPath = path.get('property');
64
+ if (!rightPath.isIdentifier()) {
65
+ return undefined;
66
+ }
67
+ const binding = path.scope.getBinding(leftPath.node.name);
68
+ const matched = binding && imports.find(imp => imp.imported !== 'side-effect' && binding.path.isAncestor(imp.local));
69
+ if (matched) {
70
+ return [matched.source, rightPath.node.name];
71
+ }
72
+ }
73
+ return undefined;
74
+ };
75
+ const getTypeImport = path => {
76
+ // We are looking for either Identifier or TSQualifiedName in path
77
+ if (path.isIdentifier()) {
78
+ const binding = path.scope.getBinding(path.node.name);
79
+ if (!binding) {
80
+ return undefined;
81
+ }
82
+ if (!binding.path.isImportSpecifier() || !binding.path.parentPath.isImportDeclaration()) {
83
+ return undefined;
84
+ }
85
+ const importDeclaration = binding.path.parentPath;
86
+ const imported = binding.path.get('imported');
87
+ const source = importDeclaration.node.source.value;
88
+ const importedNode = imported.node;
89
+ return [source, _core.types.isIdentifier(importedNode) ? importedNode.name : importedNode.value];
90
+ }
91
+ if (path.isTSQualifiedName()) {
92
+ const leftPath = path.get('left');
93
+ if (!leftPath.isIdentifier()) {
94
+ // Nested type. Not supported yet.
95
+ return undefined;
96
+ }
97
+ const rightPath = path.get('right');
98
+ const binding = path.scope.getBinding(leftPath.node.name);
99
+ if (!binding) {
100
+ return undefined;
101
+ }
102
+ if (!binding.path.isImportDefaultSpecifier() && !binding.path.isImportNamespaceSpecifier() || !binding.path.parentPath.isImportDeclaration()) {
103
+ return undefined;
104
+ }
105
+ return [binding.path.parentPath.node.source.value, rightPath.node.name];
106
+ }
107
+ return undefined;
108
+ };
109
+ const isTypeMatch = (id, types) => {
110
+ const typeAnnotation = id.get('typeAnnotation');
111
+ if (!typeAnnotation.isTSTypeAnnotation()) {
112
+ return false;
113
+ }
114
+ const typeReference = typeAnnotation.get('typeAnnotation');
115
+ if (!typeReference.isTSTypeReference()) {
116
+ return false;
117
+ }
118
+ const typeName = typeReference.get('typeName');
119
+ const matchedImport = getTypeImport(typeName);
120
+ return matchedImport !== undefined && matchedImport[0] in types && types[matchedImport[0]].includes(matchedImport[1]);
121
+ };
122
+ const isHOC = (path, hocs) => {
123
+ let calleePath = path;
124
+ while (calleePath.isCallExpression()) {
125
+ calleePath = calleePath.get('callee');
126
+ }
127
+ const matchedImport = getImport(calleePath);
128
+ return matchedImport !== undefined && matchedImport[0] in hocs && hocs[matchedImport[0]].includes(matchedImport[1]);
129
+ };
130
+ const defaultPlaceholder = '...';
131
+ const defaultReactComponentTypes = ['ExoticComponent', 'FC', 'ForwardRefExoticComponent', 'FunctionComponent', 'LazyExoticComponent', 'MemoExoticComponent', 'NamedExoticComponent'];
132
+ const removeDangerousCode = (programPath, options) => {
133
+ var _options$hocs, _options$componentTyp;
134
+ const hocs = (_options$hocs = options === null || options === void 0 ? void 0 : options.hocs) !== null && _options$hocs !== void 0 ? _options$hocs : {};
135
+ const componentTypes = (_options$componentTyp = options === null || options === void 0 ? void 0 : options.componentTypes) !== null && _options$componentTyp !== void 0 ? _options$componentTyp : {
136
+ react: [defaultPlaceholder]
137
+ };
138
+ if (Array.isArray(componentTypes.react) && componentTypes.react.includes(defaultPlaceholder)) {
139
+ const idx = componentTypes.react.indexOf(defaultPlaceholder);
140
+ componentTypes.react = [...componentTypes.react];
141
+ componentTypes.react.splice(idx, 1, ...defaultReactComponentTypes);
142
+ }
41
143
  programPath.traverse({
42
144
  // JSX can be replaced with a dummy value,
43
145
  // but we have to do it after we processed template tags.
@@ -46,6 +148,9 @@ const removeDangerousCode = programPath => {
46
148
  if ((0, _isUnnecessaryReactCall.isUnnecessaryReactCall)(p)) {
47
149
  (0, _JSXElementsRemover.JSXElementsRemover)(p);
48
150
  }
151
+ if (isHOC(p, hocs)) {
152
+ (0, _scopeHelpers.applyAction)(['replace', p, _core.types.arrowFunctionExpression([], _core.types.nullLiteral())]);
153
+ }
49
154
  }
50
155
  },
51
156
  JSXElement: {
@@ -124,6 +229,14 @@ const removeDangerousCode = programPath => {
124
229
  type: 'StringLiteral',
125
230
  value: 'undefined'
126
231
  }]);
232
+ },
233
+ VariableDeclarator(p) {
234
+ const id = p.get('id');
235
+ const init = p.get('init');
236
+ if (id.isIdentifier() && isTypeMatch(id, componentTypes) && init.isExpression()) {
237
+ // Variable is typed as a React component. We can replace its value with a null-function.
238
+ (0, _scopeHelpers.applyAction)(['replace', init, _core.types.arrowFunctionExpression([], _core.types.nullLiteral())]);
239
+ }
127
240
  }
128
241
  }, {
129
242
  globals: [],
@@ -1 +1 @@
1
- {"version":3,"file":"removeDangerousCode.js","names":["_findIdentifiers","require","_isUnnecessaryReactCall","_scopeHelpers","_JSXElementsRemover","isGlobal","id","nonType","scope","name","node","hasBinding","hasGlobal","ssrCheckFields","Set","forbiddenGlobals","isBrowserGlobal","has","isSSRCheckField","getPropertyName","path","isIdentifier","isStringLiteral","value","removeDangerousCode","programPath","traverse","CallExpression","enter","p","isUnnecessaryReactCall","JSXElementsRemover","JSXElement","JSXFragment","MemberExpression","state","obj","get","prop","windowScoped","add","globals","filter","removeWithRelated","MetaProperty","Identifier","find","parent","isTSTypeReference","parentPath","isUnaryExpression","operator","isTSTypeQuery","isClassProperty","isMemberExpression","key","push","UnaryExpression","arg","applyAction","type","exports"],"sources":["../../src/utils/removeDangerousCode.ts"],"sourcesContent":["import type { NodePath } from '@babel/core';\nimport type { Identifier, Program } from '@babel/types';\n\nimport { nonType } from './findIdentifiers';\nimport { isUnnecessaryReactCall } from './isUnnecessaryReactCall';\nimport { applyAction, removeWithRelated } from './scopeHelpers';\nimport { JSXElementsRemover } from './visitors/JSXElementsRemover';\n\nconst isGlobal = (id: NodePath<Identifier>): boolean => {\n if (!nonType(id)) {\n return false;\n }\n\n const { scope } = id;\n const { name } = id.node;\n return !scope.hasBinding(name) && scope.hasGlobal(name);\n};\n\nconst ssrCheckFields = new Set([\n 'document',\n 'location',\n 'navigator',\n 'sessionStorage',\n 'localStorage',\n 'window',\n]);\n\nconst forbiddenGlobals = new Set([\n ...ssrCheckFields,\n '$RefreshReg$',\n 'XMLHttpRequest',\n 'clearImmediate',\n 'clearInterval',\n 'clearTimeout',\n 'fetch',\n 'navigator',\n 'setImmediate',\n 'setInterval',\n 'setTimeout',\n]);\n\nconst isBrowserGlobal = (id: NodePath<Identifier>) => {\n return forbiddenGlobals.has(id.node.name) && isGlobal(id);\n};\n\nconst isSSRCheckField = (id: NodePath<Identifier>) => {\n return ssrCheckFields.has(id.node.name) && isGlobal(id);\n};\n\nconst getPropertyName = (path: NodePath): string | null => {\n if (path.isIdentifier()) {\n return path.node.name;\n }\n\n if (path.isStringLiteral()) {\n return path.node.value;\n }\n\n return null;\n};\n\nexport const removeDangerousCode = (programPath: NodePath<Program>) => {\n programPath.traverse(\n {\n // JSX can be replaced with a dummy value,\n // but we have to do it after we processed template tags.\n CallExpression: {\n enter(p) {\n if (isUnnecessaryReactCall(p)) {\n JSXElementsRemover(p);\n }\n },\n },\n JSXElement: {\n enter: JSXElementsRemover,\n },\n JSXFragment: {\n enter: JSXElementsRemover,\n },\n MemberExpression(p, state) {\n const obj = p.get('object');\n const prop = p.get('property');\n if (!obj.isIdentifier({ name: 'window' })) {\n return;\n }\n\n const name = getPropertyName(prop);\n if (!name) {\n return;\n }\n\n state.windowScoped.add(name);\n // eslint-disable-next-line no-param-reassign\n state.globals = state.globals.filter((id) => {\n if (id.node.name === name) {\n removeWithRelated([id]);\n return false;\n }\n\n return true;\n });\n },\n MetaProperty(p) {\n // Remove all references to `import.meta`\n removeWithRelated([p]);\n },\n Identifier(p, state) {\n if (p.find((parent) => parent.isTSTypeReference())) {\n // don't mess with TS type references\n return;\n }\n if (isBrowserGlobal(p)) {\n if (\n p.find(\n (parentPath) =>\n parentPath.isUnaryExpression({ operator: 'typeof' }) ||\n parentPath.isTSTypeQuery()\n )\n ) {\n // Ignore `typeof window` expressions\n return;\n }\n\n if (p.parentPath.isClassProperty()) {\n // ignore class property decls\n return;\n }\n if (p.parentPath.isMemberExpression() && p.key === 'property') {\n // ignore e.g this.fetch()\n // window.fetch will be handled by the windowScoped block below\n return;\n }\n\n removeWithRelated([p]);\n\n return;\n }\n\n if (state.windowScoped.has(p.node.name)) {\n removeWithRelated([p]);\n } else if (isGlobal(p)) {\n state.globals.push(p);\n }\n },\n\n // Since we can use happy-dom, typical SSR checks may not work as expected.\n // We need to detect them and replace with an \"undefined\" literal.\n UnaryExpression(p) {\n if (p.node.operator !== 'typeof') {\n return;\n }\n const arg = p.get('argument');\n if (!arg.isIdentifier() || !isSSRCheckField(arg)) {\n return;\n }\n\n applyAction([\n 'replace',\n p,\n { type: 'StringLiteral', value: 'undefined' },\n ]);\n },\n },\n {\n globals: [] as NodePath<Identifier>[],\n windowScoped: new Set<string>(),\n }\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"removeDangerousCode.js","names":["_core","require","_findIdentifiers","_isUnnecessaryReactCall","_scopeHelpers","_JSXElementsRemover","_collectExportsAndImports","isGlobal","id","nonType","scope","name","node","hasBinding","hasGlobal","ssrCheckFields","Set","forbiddenGlobals","isBrowserGlobal","has","isSSRCheckField","getPropertyName","path","isIdentifier","isStringLiteral","value","getImport","programPath","findParent","p","isProgram","undefined","imports","collectExportsAndImports","binding","getBinding","matched","find","imp","imported","isAncestor","local","source","isMemberExpression","leftPath","get","rightPath","getTypeImport","isImportSpecifier","parentPath","isImportDeclaration","importDeclaration","importedNode","t","isTSQualifiedName","isImportDefaultSpecifier","isImportNamespaceSpecifier","isTypeMatch","types","typeAnnotation","isTSTypeAnnotation","typeReference","isTSTypeReference","typeName","matchedImport","includes","isHOC","hocs","calleePath","isCallExpression","defaultPlaceholder","defaultReactComponentTypes","removeDangerousCode","options","_options$hocs","_options$componentTyp","componentTypes","react","Array","isArray","idx","indexOf","splice","traverse","CallExpression","enter","isUnnecessaryReactCall","JSXElementsRemover","applyAction","arrowFunctionExpression","nullLiteral","JSXElement","JSXFragment","MemberExpression","state","obj","prop","windowScoped","add","globals","filter","removeWithRelated","MetaProperty","Identifier","parent","isUnaryExpression","operator","isTSTypeQuery","isClassProperty","key","push","UnaryExpression","arg","type","VariableDeclarator","init","isExpression","exports"],"sources":["../../src/utils/removeDangerousCode.ts"],"sourcesContent":["import type { NodePath } from '@babel/core';\nimport { types as t } from '@babel/core';\nimport type {\n CallExpression,\n Expression,\n Identifier,\n Program,\n V8IntrinsicIdentifier,\n} from '@babel/types';\n\nimport type { CodeRemoverOptions } from '@wyw-in-js/shared';\nimport { nonType } from './findIdentifiers';\nimport { isUnnecessaryReactCall } from './isUnnecessaryReactCall';\nimport { applyAction, removeWithRelated } from './scopeHelpers';\nimport { JSXElementsRemover } from './visitors/JSXElementsRemover';\nimport type { IImport } from './collectExportsAndImports';\nimport { collectExportsAndImports } from './collectExportsAndImports';\n\nconst isGlobal = (id: NodePath<Identifier>): boolean => {\n if (!nonType(id)) {\n return false;\n }\n\n const { scope } = id;\n const { name } = id.node;\n return !scope.hasBinding(name) && scope.hasGlobal(name);\n};\n\nconst ssrCheckFields = new Set([\n 'document',\n 'location',\n 'navigator',\n 'sessionStorage',\n 'localStorage',\n 'window',\n]);\n\nconst forbiddenGlobals = new Set([\n ...ssrCheckFields,\n '$RefreshReg$',\n 'XMLHttpRequest',\n 'clearImmediate',\n 'clearInterval',\n 'clearTimeout',\n 'fetch',\n 'navigator',\n 'setImmediate',\n 'setInterval',\n 'setTimeout',\n]);\n\nconst isBrowserGlobal = (id: NodePath<Identifier>) => {\n return forbiddenGlobals.has(id.node.name) && isGlobal(id);\n};\n\nconst isSSRCheckField = (id: NodePath<Identifier>) => {\n return ssrCheckFields.has(id.node.name) && isGlobal(id);\n};\n\nconst getPropertyName = (path: NodePath): string | null => {\n if (path.isIdentifier()) {\n return path.node.name;\n }\n\n if (path.isStringLiteral()) {\n return path.node.value;\n }\n\n return null;\n};\n\nconst getImport = (path: NodePath): [string, string] | undefined => {\n const programPath = path.findParent((p) => p.isProgram()) as\n | NodePath<Program>\n | undefined;\n if (!programPath) {\n return undefined;\n }\n\n const { imports } = collectExportsAndImports(programPath);\n\n if (path.isIdentifier()) {\n const binding = path.scope.getBinding(path.node.name);\n const matched =\n binding &&\n imports.find(\n (imp): imp is IImport =>\n imp.imported !== 'side-effect' && binding.path.isAncestor(imp.local)\n );\n\n if (matched) {\n return [matched.source, matched.imported];\n }\n }\n\n if (path.isMemberExpression()) {\n const leftPath = path.get('object');\n if (!leftPath.isIdentifier()) {\n // Nested member expression. Not supported yet.\n return undefined;\n }\n\n const rightPath = path.get('property');\n if (!rightPath.isIdentifier()) {\n return undefined;\n }\n\n const binding = path.scope.getBinding(leftPath.node.name);\n const matched =\n binding &&\n imports.find(\n (imp): imp is IImport =>\n imp.imported !== 'side-effect' && binding.path.isAncestor(imp.local)\n );\n\n if (matched) {\n return [matched.source, rightPath.node.name];\n }\n }\n\n return undefined;\n};\n\nconst getTypeImport = (path: NodePath): [string, string] | undefined => {\n // We are looking for either Identifier or TSQualifiedName in path\n if (path.isIdentifier()) {\n const binding = path.scope.getBinding(path.node.name);\n if (!binding) {\n return undefined;\n }\n\n if (\n !binding.path.isImportSpecifier() ||\n !binding.path.parentPath.isImportDeclaration()\n ) {\n return undefined;\n }\n\n const importDeclaration = binding.path.parentPath;\n const imported = binding.path.get('imported');\n const source = importDeclaration.node.source.value;\n const importedNode = imported.node;\n return [\n source,\n t.isIdentifier(importedNode) ? importedNode.name : importedNode.value,\n ];\n }\n\n if (path.isTSQualifiedName()) {\n const leftPath = path.get('left');\n if (!leftPath.isIdentifier()) {\n // Nested type. Not supported yet.\n return undefined;\n }\n\n const rightPath = path.get('right');\n\n const binding = path.scope.getBinding(leftPath.node.name);\n if (!binding) {\n return undefined;\n }\n\n if (\n (!binding.path.isImportDefaultSpecifier() &&\n !binding.path.isImportNamespaceSpecifier()) ||\n !binding.path.parentPath.isImportDeclaration()\n ) {\n return undefined;\n }\n\n return [binding.path.parentPath.node.source.value, rightPath.node.name];\n }\n\n return undefined;\n};\n\nconst isTypeMatch = (\n id: NodePath<Identifier>,\n types: Record<string, string[]>\n): boolean => {\n const typeAnnotation = id.get('typeAnnotation');\n if (!typeAnnotation.isTSTypeAnnotation()) {\n return false;\n }\n\n const typeReference = typeAnnotation.get('typeAnnotation');\n if (!typeReference.isTSTypeReference()) {\n return false;\n }\n\n const typeName = typeReference.get('typeName');\n const matchedImport = getTypeImport(typeName);\n return (\n matchedImport !== undefined &&\n matchedImport[0] in types &&\n types[matchedImport[0]].includes(matchedImport[1])\n );\n};\n\nconst isHOC = (\n path: NodePath<CallExpression>,\n hocs: Record<string, string[]>\n) => {\n let calleePath: NodePath<V8IntrinsicIdentifier | Expression> = path;\n while (calleePath.isCallExpression()) {\n calleePath = calleePath.get('callee');\n }\n\n const matchedImport = getImport(calleePath);\n return (\n matchedImport !== undefined &&\n matchedImport[0] in hocs &&\n hocs[matchedImport[0]].includes(matchedImport[1])\n );\n};\n\nconst defaultPlaceholder = '...';\n\nconst defaultReactComponentTypes = [\n 'ExoticComponent',\n 'FC',\n 'ForwardRefExoticComponent',\n 'FunctionComponent',\n 'LazyExoticComponent',\n 'MemoExoticComponent',\n 'NamedExoticComponent',\n];\n\nexport const removeDangerousCode = (\n programPath: NodePath<Program>,\n options?: CodeRemoverOptions\n) => {\n const hocs = options?.hocs ?? {};\n\n const componentTypes = options?.componentTypes ?? {\n react: [defaultPlaceholder],\n };\n\n if (\n Array.isArray(componentTypes.react) &&\n componentTypes.react.includes(defaultPlaceholder)\n ) {\n const idx = componentTypes.react.indexOf(defaultPlaceholder);\n componentTypes.react = [...componentTypes.react];\n componentTypes.react.splice(idx, 1, ...defaultReactComponentTypes);\n }\n\n programPath.traverse(\n {\n // JSX can be replaced with a dummy value,\n // but we have to do it after we processed template tags.\n CallExpression: {\n enter(p) {\n if (isUnnecessaryReactCall(p)) {\n JSXElementsRemover(p);\n }\n\n if (isHOC(p, hocs)) {\n applyAction([\n 'replace',\n p,\n t.arrowFunctionExpression([], t.nullLiteral()),\n ]);\n }\n },\n },\n JSXElement: {\n enter: JSXElementsRemover,\n },\n JSXFragment: {\n enter: JSXElementsRemover,\n },\n MemberExpression(p, state) {\n const obj = p.get('object');\n const prop = p.get('property');\n if (!obj.isIdentifier({ name: 'window' })) {\n return;\n }\n\n const name = getPropertyName(prop);\n if (!name) {\n return;\n }\n\n state.windowScoped.add(name);\n // eslint-disable-next-line no-param-reassign\n state.globals = state.globals.filter((id) => {\n if (id.node.name === name) {\n removeWithRelated([id]);\n return false;\n }\n\n return true;\n });\n },\n MetaProperty(p) {\n // Remove all references to `import.meta`\n removeWithRelated([p]);\n },\n Identifier(p, state) {\n if (p.find((parent) => parent.isTSTypeReference())) {\n // don't mess with TS type references\n return;\n }\n if (isBrowserGlobal(p)) {\n if (\n p.find(\n (parentPath) =>\n parentPath.isUnaryExpression({ operator: 'typeof' }) ||\n parentPath.isTSTypeQuery()\n )\n ) {\n // Ignore `typeof window` expressions\n return;\n }\n\n if (p.parentPath.isClassProperty()) {\n // ignore class property decls\n return;\n }\n if (p.parentPath.isMemberExpression() && p.key === 'property') {\n // ignore e.g this.fetch()\n // window.fetch will be handled by the windowScoped block below\n return;\n }\n\n removeWithRelated([p]);\n\n return;\n }\n\n if (state.windowScoped.has(p.node.name)) {\n removeWithRelated([p]);\n } else if (isGlobal(p)) {\n state.globals.push(p);\n }\n },\n\n // Since we can use happy-dom, typical SSR checks may not work as expected.\n // We need to detect them and replace with an \"undefined\" literal.\n UnaryExpression(p) {\n if (p.node.operator !== 'typeof') {\n return;\n }\n const arg = p.get('argument');\n if (!arg.isIdentifier() || !isSSRCheckField(arg)) {\n return;\n }\n\n applyAction([\n 'replace',\n p,\n { type: 'StringLiteral', value: 'undefined' },\n ]);\n },\n VariableDeclarator(p) {\n const id = p.get('id');\n const init = p.get('init');\n if (\n id.isIdentifier() &&\n isTypeMatch(id, componentTypes) &&\n init.isExpression()\n ) {\n // Variable is typed as a React component. We can replace its value with a null-function.\n applyAction([\n 'replace',\n init,\n t.arrowFunctionExpression([], t.nullLiteral()),\n ]);\n }\n },\n },\n {\n globals: [] as NodePath<Identifier>[],\n windowScoped: new Set<string>(),\n }\n );\n};\n"],"mappings":"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"}
@@ -3,9 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.invalidateTraversalCache = exports.getTraversalCache = exports.clearBabelTraversalCache = void 0;
7
- var _traverse = _interopRequireDefault(require("@babel/traverse"));
8
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6
+ exports.invalidateTraversalCache = exports.getTraversalCache = void 0;
9
7
  const caches = new WeakMap();
10
8
  const getTraversalCache = (path, name) => {
11
9
  const programPath = path.find(p => p.isProgram());
@@ -22,11 +20,6 @@ const getTraversalCache = (path, name) => {
22
20
  return cache.get(name);
23
21
  };
24
22
  exports.getTraversalCache = getTraversalCache;
25
- const traverseCache = _traverse.default.cache;
26
- const clearBabelTraversalCache = () => {
27
- traverseCache.clear();
28
- };
29
- exports.clearBabelTraversalCache = clearBabelTraversalCache;
30
23
  const invalidateTraversalCache = path => {
31
24
  const programPath = path.find(p => p.isProgram());
32
25
  if (!programPath) {
@@ -1 +1 @@
1
- {"version":3,"file":"traversalCache.js","names":["_traverse","_interopRequireDefault","require","obj","__esModule","default","caches","WeakMap","getTraversalCache","path","name","programPath","find","p","isProgram","Error","node","type","has","set","Map","cache","get","exports","traverseCache","traverse","clearBabelTraversalCache","clear","invalidateTraversalCache","delete"],"sources":["../../src/utils/traversalCache.ts"],"sourcesContent":["import type { NodePath } from '@babel/traverse';\nimport traverse from '@babel/traverse';\nimport type { Node } from '@babel/types';\n\nconst caches = new WeakMap<\n NodePath,\n Map<string, WeakMap<NodePath | Node, unknown>>\n>();\n\nexport const getTraversalCache = <\n TValue,\n TKey extends NodePath | Node = NodePath,\n>(\n path: NodePath,\n name: string\n) => {\n const programPath = path.find((p) => p.isProgram());\n if (!programPath) {\n throw new Error(`Could not find program for ${path.node.type}`);\n }\n\n if (!caches.has(programPath)) {\n caches.set(programPath, new Map());\n }\n\n const cache = caches.get(programPath)!;\n if (!cache.has(name)) {\n cache.set(name, new WeakMap());\n }\n\n return cache.get(name) as WeakMap<TKey, TValue>;\n};\n\nconst traverseCache = (traverse as unknown as { cache: unknown }).cache;\nexport const clearBabelTraversalCache = () => {\n (traverseCache as { clear: () => void }).clear();\n};\n\nexport const invalidateTraversalCache = (path: NodePath) => {\n const programPath = path.find((p) => p.isProgram());\n if (!programPath) {\n throw new Error(`Could not find program for ${path.node.type}`);\n }\n\n caches.delete(programPath);\n};\n"],"mappings":";;;;;;AACA,IAAAA,SAAA,GAAAC,sBAAA,CAAAC,OAAA;AAAuC,SAAAD,uBAAAE,GAAA,WAAAA,GAAA,IAAAA,GAAA,CAAAC,UAAA,GAAAD,GAAA,KAAAE,OAAA,EAAAF,GAAA;AAGvC,MAAMG,MAAM,GAAG,IAAIC,OAAO,CAGxB,CAAC;AAEI,MAAMC,iBAAiB,GAAGA,CAI/BC,IAAc,EACdC,IAAY,KACT;EACH,MAAMC,WAAW,GAAGF,IAAI,CAACG,IAAI,CAAEC,CAAC,IAAKA,CAAC,CAACC,SAAS,CAAC,CAAC,CAAC;EACnD,IAAI,CAACH,WAAW,EAAE;IAChB,MAAM,IAAII,KAAK,CAAE,8BAA6BN,IAAI,CAACO,IAAI,CAACC,IAAK,EAAC,CAAC;EACjE;EAEA,IAAI,CAACX,MAAM,CAACY,GAAG,CAACP,WAAW,CAAC,EAAE;IAC5BL,MAAM,CAACa,GAAG,CAACR,WAAW,EAAE,IAAIS,GAAG,CAAC,CAAC,CAAC;EACpC;EAEA,MAAMC,KAAK,GAAGf,MAAM,CAACgB,GAAG,CAACX,WAAW,CAAE;EACtC,IAAI,CAACU,KAAK,CAACH,GAAG,CAACR,IAAI,CAAC,EAAE;IACpBW,KAAK,CAACF,GAAG,CAACT,IAAI,EAAE,IAAIH,OAAO,CAAC,CAAC,CAAC;EAChC;EAEA,OAAOc,KAAK,CAACC,GAAG,CAACZ,IAAI,CAAC;AACxB,CAAC;AAACa,OAAA,CAAAf,iBAAA,GAAAA,iBAAA;AAEF,MAAMgB,aAAa,GAAIC,iBAAQ,CAAmCJ,KAAK;AAChE,MAAMK,wBAAwB,GAAGA,CAAA,KAAM;EAC3CF,aAAa,CAA2BG,KAAK,CAAC,CAAC;AAClD,CAAC;AAACJ,OAAA,CAAAG,wBAAA,GAAAA,wBAAA;AAEK,MAAME,wBAAwB,GAAInB,IAAc,IAAK;EAC1D,MAAME,WAAW,GAAGF,IAAI,CAACG,IAAI,CAAEC,CAAC,IAAKA,CAAC,CAACC,SAAS,CAAC,CAAC,CAAC;EACnD,IAAI,CAACH,WAAW,EAAE;IAChB,MAAM,IAAII,KAAK,CAAE,8BAA6BN,IAAI,CAACO,IAAI,CAACC,IAAK,EAAC,CAAC;EACjE;EAEAX,MAAM,CAACuB,MAAM,CAAClB,WAAW,CAAC;AAC5B,CAAC;AAACY,OAAA,CAAAK,wBAAA,GAAAA,wBAAA"}
1
+ {"version":3,"file":"traversalCache.js","names":["caches","WeakMap","getTraversalCache","path","name","programPath","find","p","isProgram","Error","node","type","has","set","Map","cache","get","exports","invalidateTraversalCache","delete"],"sources":["../../src/utils/traversalCache.ts"],"sourcesContent":["import type { NodePath } from '@babel/traverse';\nimport type { Node } from '@babel/types';\n\nconst caches = new WeakMap<\n NodePath,\n Map<string, WeakMap<NodePath | Node, unknown>>\n>();\n\nexport const getTraversalCache = <\n TValue,\n TKey extends NodePath | Node = NodePath,\n>(\n path: NodePath,\n name: string\n) => {\n const programPath = path.find((p) => p.isProgram());\n if (!programPath) {\n throw new Error(`Could not find program for ${path.node.type}`);\n }\n\n if (!caches.has(programPath)) {\n caches.set(programPath, new Map());\n }\n\n const cache = caches.get(programPath)!;\n if (!cache.has(name)) {\n cache.set(name, new WeakMap());\n }\n\n return cache.get(name) as WeakMap<TKey, TValue>;\n};\n\nexport const invalidateTraversalCache = (path: NodePath) => {\n const programPath = path.find((p) => p.isProgram());\n if (!programPath) {\n throw new Error(`Could not find program for ${path.node.type}`);\n }\n\n caches.delete(programPath);\n};\n"],"mappings":";;;;;;AAGA,MAAMA,MAAM,GAAG,IAAIC,OAAO,CAGxB,CAAC;AAEI,MAAMC,iBAAiB,GAAGA,CAI/BC,IAAc,EACdC,IAAY,KACT;EACH,MAAMC,WAAW,GAAGF,IAAI,CAACG,IAAI,CAAEC,CAAC,IAAKA,CAAC,CAACC,SAAS,CAAC,CAAC,CAAC;EACnD,IAAI,CAACH,WAAW,EAAE;IAChB,MAAM,IAAII,KAAK,CAAE,8BAA6BN,IAAI,CAACO,IAAI,CAACC,IAAK,EAAC,CAAC;EACjE;EAEA,IAAI,CAACX,MAAM,CAACY,GAAG,CAACP,WAAW,CAAC,EAAE;IAC5BL,MAAM,CAACa,GAAG,CAACR,WAAW,EAAE,IAAIS,GAAG,CAAC,CAAC,CAAC;EACpC;EAEA,MAAMC,KAAK,GAAGf,MAAM,CAACgB,GAAG,CAACX,WAAW,CAAE;EACtC,IAAI,CAACU,KAAK,CAACH,GAAG,CAACR,IAAI,CAAC,EAAE;IACpBW,KAAK,CAACF,GAAG,CAACT,IAAI,EAAE,IAAIH,OAAO,CAAC,CAAC,CAAC;EAChC;EAEA,OAAOc,KAAK,CAACC,GAAG,CAACZ,IAAI,CAAC;AACxB,CAAC;AAACa,OAAA,CAAAf,iBAAA,GAAAA,iBAAA;AAEK,MAAMgB,wBAAwB,GAAIf,IAAc,IAAK;EAC1D,MAAME,WAAW,GAAGF,IAAI,CAACG,IAAI,CAAEC,CAAC,IAAKA,CAAC,CAACC,SAAS,CAAC,CAAC,CAAC;EACnD,IAAI,CAACH,WAAW,EAAE;IAChB,MAAM,IAAII,KAAK,CAAE,8BAA6BN,IAAI,CAACO,IAAI,CAACC,IAAK,EAAC,CAAC;EACjE;EAEAX,MAAM,CAACmB,MAAM,CAACd,WAAW,CAAC;AAC5B,CAAC;AAACY,OAAA,CAAAC,wBAAA,GAAAA,wBAAA"}
@@ -23,14 +23,25 @@ function createWindow() {
23
23
  win.Uint8Array = Uint8Array;
24
24
  return win;
25
25
  }
26
+
27
+ /**
28
+ * `happy-dom` already has required references, so we don't need to set them.
29
+ */
30
+ function setReferencePropertyIfNotPresent(context, key) {
31
+ if (context[key] === context) {
32
+ return;
33
+ }
34
+ context[key] = context;
35
+ }
26
36
  function createBaseContext(win, additionalContext) {
27
37
  const baseContext = win !== null && win !== void 0 ? win : {};
38
+ setReferencePropertyIfNotPresent(baseContext, 'window');
39
+ setReferencePropertyIfNotPresent(baseContext, 'self');
40
+ setReferencePropertyIfNotPresent(baseContext, 'top');
41
+ setReferencePropertyIfNotPresent(baseContext, 'parent');
42
+ setReferencePropertyIfNotPresent(baseContext, 'global');
43
+ setReferencePropertyIfNotPresent(baseContext, 'process');
28
44
  baseContext.document = win === null || win === void 0 ? void 0 : win.document;
29
- baseContext.window = win;
30
- baseContext.self = win;
31
- baseContext.top = win;
32
- baseContext.parent = win;
33
- baseContext.global = win;
34
45
  baseContext.process = process;
35
46
  baseContext.clearImmediate = NOOP;
36
47
  baseContext.clearInterval = NOOP;
@@ -50,7 +61,7 @@ function createHappyDOMWindow() {
50
61
  const win = createWindow();
51
62
  return {
52
63
  teardown: () => {
53
- win.happyDOM.cancelAsync();
64
+ win.happyDOM.abort();
54
65
  },
55
66
  window: win
56
67
  };
@@ -1 +1 @@
1
- {"version":3,"file":"createVmContext.js","names":["vm","_interopRequireWildcard","require","_shared","process","_getRequireWildcardCache","e","WeakMap","r","t","__esModule","default","has","get","n","__proto__","a","Object","defineProperty","getOwnPropertyDescriptor","u","prototype","hasOwnProperty","call","i","set","NOOP","createWindow","Window","GlobalWindow","HappyWindow","win","Buffer","Uint8Array","createBaseContext","additionalContext","baseContext","document","window","self","top","parent","global","clearImmediate","clearInterval","clearTimeout","setImmediate","requestAnimationFrame","setInterval","setTimeout","key","createHappyDOMWindow","teardown","happyDOM","cancelAsync","createNothing","undefined","createVmContext","filename","features","overrideContext","isHappyDOMEnabled","isFeatureEnabled","__filename","context","createContext"],"sources":["../../src/vm/createVmContext.ts"],"sourcesContent":["import * as vm from 'vm';\n\nimport type { Window } from 'happy-dom';\n\nimport type { FeatureFlags, StrictOptions } from '@wyw-in-js/shared';\nimport { isFeatureEnabled } from '@wyw-in-js/shared';\n\nimport * as process from './process';\n\nconst NOOP = () => {};\n\nfunction createWindow(): Window {\n const { Window, GlobalWindow } = require('happy-dom');\n const HappyWindow = GlobalWindow || Window;\n const win = new HappyWindow();\n\n // TODO: browser doesn't expose Buffer, but a lot of dependencies use it\n win.Buffer = Buffer;\n win.Uint8Array = Uint8Array;\n\n return win;\n}\n\nfunction createBaseContext(\n win: Window | undefined,\n additionalContext: Partial<vm.Context>\n): Partial<vm.Context> {\n const baseContext: vm.Context = win ?? {};\n\n baseContext.document = win?.document;\n baseContext.window = win;\n baseContext.self = win;\n baseContext.top = win;\n baseContext.parent = win;\n baseContext.global = win;\n\n baseContext.process = process;\n\n baseContext.clearImmediate = NOOP;\n baseContext.clearInterval = NOOP;\n baseContext.clearTimeout = NOOP;\n baseContext.setImmediate = NOOP;\n baseContext.requestAnimationFrame = NOOP;\n baseContext.setInterval = NOOP;\n baseContext.setTimeout = NOOP;\n\n // eslint-disable-next-line guard-for-in,no-restricted-syntax\n for (const key in additionalContext) {\n baseContext[key] = additionalContext[key];\n }\n\n return baseContext;\n}\n\nfunction createHappyDOMWindow() {\n const win = createWindow();\n\n return {\n teardown: () => {\n win.happyDOM.cancelAsync();\n },\n window: win,\n };\n}\n\nfunction createNothing() {\n return {\n teardown: () => {},\n window: undefined,\n };\n}\n\nexport function createVmContext(\n filename: string,\n features: FeatureFlags<'happyDOM'>,\n additionalContext: Partial<vm.Context>,\n overrideContext: StrictOptions['overrideContext'] = (i) => i\n) {\n const isHappyDOMEnabled = isFeatureEnabled(features, 'happyDOM', filename);\n\n const { teardown, window } = isHappyDOMEnabled\n ? createHappyDOMWindow()\n : createNothing();\n const baseContext = createBaseContext(\n window,\n overrideContext(\n {\n __filename: filename,\n ...additionalContext,\n },\n filename\n )\n );\n\n const context = vm.createContext(baseContext);\n\n return {\n context,\n teardown,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"createVmContext.js","names":["vm","_interopRequireWildcard","require","_shared","process","_getRequireWildcardCache","e","WeakMap","r","t","__esModule","default","has","get","n","__proto__","a","Object","defineProperty","getOwnPropertyDescriptor","u","prototype","hasOwnProperty","call","i","set","NOOP","createWindow","Window","GlobalWindow","HappyWindow","win","Buffer","Uint8Array","setReferencePropertyIfNotPresent","context","key","createBaseContext","additionalContext","baseContext","document","clearImmediate","clearInterval","clearTimeout","setImmediate","requestAnimationFrame","setInterval","setTimeout","createHappyDOMWindow","teardown","happyDOM","abort","window","createNothing","undefined","createVmContext","filename","features","overrideContext","isHappyDOMEnabled","isFeatureEnabled","__filename","createContext"],"sources":["../../src/vm/createVmContext.ts"],"sourcesContent":["import * as vm from 'vm';\n\nimport type { Window } from 'happy-dom';\n\nimport type { FeatureFlags, StrictOptions } from '@wyw-in-js/shared';\nimport { isFeatureEnabled } from '@wyw-in-js/shared';\n\nimport * as process from './process';\n\nconst NOOP = () => {};\n\nfunction createWindow(): Window {\n const { Window, GlobalWindow } = require('happy-dom');\n const HappyWindow = GlobalWindow || Window;\n const win = new HappyWindow();\n\n // TODO: browser doesn't expose Buffer, but a lot of dependencies use it\n win.Buffer = Buffer;\n win.Uint8Array = Uint8Array;\n\n return win;\n}\n\n/**\n * `happy-dom` already has required references, so we don't need to set them.\n */\nfunction setReferencePropertyIfNotPresent(\n context: vm.Context,\n key: string\n): void {\n if (context[key] === context) {\n return;\n }\n\n context[key] = context;\n}\n\nfunction createBaseContext(\n win: Window | undefined,\n additionalContext: Partial<vm.Context>\n): Partial<vm.Context> {\n const baseContext: vm.Context = win ?? {};\n\n setReferencePropertyIfNotPresent(baseContext, 'window');\n setReferencePropertyIfNotPresent(baseContext, 'self');\n setReferencePropertyIfNotPresent(baseContext, 'top');\n setReferencePropertyIfNotPresent(baseContext, 'parent');\n setReferencePropertyIfNotPresent(baseContext, 'global');\n setReferencePropertyIfNotPresent(baseContext, 'process');\n\n baseContext.document = win?.document;\n baseContext.process = process;\n\n baseContext.clearImmediate = NOOP;\n baseContext.clearInterval = NOOP;\n baseContext.clearTimeout = NOOP;\n baseContext.setImmediate = NOOP;\n baseContext.requestAnimationFrame = NOOP;\n baseContext.setInterval = NOOP;\n baseContext.setTimeout = NOOP;\n\n // eslint-disable-next-line guard-for-in,no-restricted-syntax\n for (const key in additionalContext) {\n baseContext[key] = additionalContext[key];\n }\n\n return baseContext;\n}\n\nfunction createHappyDOMWindow() {\n const win = createWindow();\n\n return {\n teardown: () => {\n win.happyDOM.abort();\n },\n window: win,\n };\n}\n\nfunction createNothing() {\n return {\n teardown: () => {},\n window: undefined,\n };\n}\n\nexport function createVmContext(\n filename: string,\n features: FeatureFlags<'happyDOM'>,\n additionalContext: Partial<vm.Context>,\n overrideContext: StrictOptions['overrideContext'] = (i) => i\n) {\n const isHappyDOMEnabled = isFeatureEnabled(features, 'happyDOM', filename);\n\n const { teardown, window } = isHappyDOMEnabled\n ? createHappyDOMWindow()\n : createNothing();\n const baseContext = createBaseContext(\n window,\n overrideContext(\n {\n __filename: filename,\n ...additionalContext,\n },\n filename\n )\n );\n\n const context = vm.createContext(baseContext);\n\n return {\n context,\n teardown,\n };\n}\n"],"mappings":";;;;;;AAAA,IAAAA,EAAA,GAAAC,uBAAA,CAAAC,OAAA;AAKA,IAAAC,OAAA,GAAAD,OAAA;AAEA,IAAAE,OAAA,GAAAH,uBAAA,CAAAC,OAAA;AAAqC,SAAAG,yBAAAC,CAAA,6BAAAC,OAAA,mBAAAC,CAAA,OAAAD,OAAA,IAAAE,CAAA,OAAAF,OAAA,YAAAF,wBAAA,YAAAA,CAAAC,CAAA,WAAAA,CAAA,GAAAG,CAAA,GAAAD,CAAA,KAAAF,CAAA;AAAA,SAAAL,wBAAAK,CAAA,EAAAE,CAAA,SAAAA,CAAA,IAAAF,CAAA,IAAAA,CAAA,CAAAI,UAAA,SAAAJ,CAAA,eAAAA,CAAA,uBAAAA,CAAA,yBAAAA,CAAA,WAAAK,OAAA,EAAAL,CAAA,QAAAG,CAAA,GAAAJ,wBAAA,CAAAG,CAAA,OAAAC,CAAA,IAAAA,CAAA,CAAAG,GAAA,CAAAN,CAAA,UAAAG,CAAA,CAAAI,GAAA,CAAAP,CAAA,OAAAQ,CAAA,KAAAC,SAAA,UAAAC,CAAA,GAAAC,MAAA,CAAAC,cAAA,IAAAD,MAAA,CAAAE,wBAAA,WAAAC,CAAA,IAAAd,CAAA,oBAAAc,CAAA,IAAAH,MAAA,CAAAI,SAAA,CAAAC,cAAA,CAAAC,IAAA,CAAAjB,CAAA,EAAAc,CAAA,SAAAI,CAAA,GAAAR,CAAA,GAAAC,MAAA,CAAAE,wBAAA,CAAAb,CAAA,EAAAc,CAAA,UAAAI,CAAA,KAAAA,CAAA,CAAAX,GAAA,IAAAW,CAAA,CAAAC,GAAA,IAAAR,MAAA,CAAAC,cAAA,CAAAJ,CAAA,EAAAM,CAAA,EAAAI,CAAA,IAAAV,CAAA,CAAAM,CAAA,IAAAd,CAAA,CAAAc,CAAA,YAAAN,CAAA,CAAAH,OAAA,GAAAL,CAAA,EAAAG,CAAA,IAAAA,CAAA,CAAAgB,GAAA,CAAAnB,CAAA,EAAAQ,CAAA,GAAAA,CAAA;AAErC,MAAMY,IAAI,GAAGA,CAAA,KAAM,CAAC,CAAC;AAErB,SAASC,YAAYA,CAAA,EAAW;EAC9B,MAAM;IAAEC,MAAM;IAAEC;EAAa,CAAC,GAAG3B,OAAO,CAAC,WAAW,CAAC;EACrD,MAAM4B,WAAW,GAAGD,YAAY,IAAID,MAAM;EAC1C,MAAMG,GAAG,GAAG,IAAID,WAAW,CAAC,CAAC;;EAE7B;EACAC,GAAG,CAACC,MAAM,GAAGA,MAAM;EACnBD,GAAG,CAACE,UAAU,GAAGA,UAAU;EAE3B,OAAOF,GAAG;AACZ;;AAEA;AACA;AACA;AACA,SAASG,gCAAgCA,CACvCC,OAAmB,EACnBC,GAAW,EACL;EACN,IAAID,OAAO,CAACC,GAAG,CAAC,KAAKD,OAAO,EAAE;IAC5B;EACF;EAEAA,OAAO,CAACC,GAAG,CAAC,GAAGD,OAAO;AACxB;AAEA,SAASE,iBAAiBA,CACxBN,GAAuB,EACvBO,iBAAsC,EACjB;EACrB,MAAMC,WAAuB,GAAGR,GAAG,aAAHA,GAAG,cAAHA,GAAG,GAAI,CAAC,CAAC;EAEzCG,gCAAgC,CAACK,WAAW,EAAE,QAAQ,CAAC;EACvDL,gCAAgC,CAACK,WAAW,EAAE,MAAM,CAAC;EACrDL,gCAAgC,CAACK,WAAW,EAAE,KAAK,CAAC;EACpDL,gCAAgC,CAACK,WAAW,EAAE,QAAQ,CAAC;EACvDL,gCAAgC,CAACK,WAAW,EAAE,QAAQ,CAAC;EACvDL,gCAAgC,CAACK,WAAW,EAAE,SAAS,CAAC;EAExDA,WAAW,CAACC,QAAQ,GAAGT,GAAG,aAAHA,GAAG,uBAAHA,GAAG,CAAES,QAAQ;EACpCD,WAAW,CAACnC,OAAO,GAAGA,OAAO;EAE7BmC,WAAW,CAACE,cAAc,GAAGf,IAAI;EACjCa,WAAW,CAACG,aAAa,GAAGhB,IAAI;EAChCa,WAAW,CAACI,YAAY,GAAGjB,IAAI;EAC/Ba,WAAW,CAACK,YAAY,GAAGlB,IAAI;EAC/Ba,WAAW,CAACM,qBAAqB,GAAGnB,IAAI;EACxCa,WAAW,CAACO,WAAW,GAAGpB,IAAI;EAC9Ba,WAAW,CAACQ,UAAU,GAAGrB,IAAI;;EAE7B;EACA,KAAK,MAAMU,GAAG,IAAIE,iBAAiB,EAAE;IACnCC,WAAW,CAACH,GAAG,CAAC,GAAGE,iBAAiB,CAACF,GAAG,CAAC;EAC3C;EAEA,OAAOG,WAAW;AACpB;AAEA,SAASS,oBAAoBA,CAAA,EAAG;EAC9B,MAAMjB,GAAG,GAAGJ,YAAY,CAAC,CAAC;EAE1B,OAAO;IACLsB,QAAQ,EAAEA,CAAA,KAAM;MACdlB,GAAG,CAACmB,QAAQ,CAACC,KAAK,CAAC,CAAC;IACtB,CAAC;IACDC,MAAM,EAAErB;EACV,CAAC;AACH;AAEA,SAASsB,aAAaA,CAAA,EAAG;EACvB,OAAO;IACLJ,QAAQ,EAAEA,CAAA,KAAM,CAAC,CAAC;IAClBG,MAAM,EAAEE;EACV,CAAC;AACH;AAEO,SAASC,eAAeA,CAC7BC,QAAgB,EAChBC,QAAkC,EAClCnB,iBAAsC,EACtCoB,eAAiD,GAAIlC,CAAC,IAAKA,CAAC,EAC5D;EACA,MAAMmC,iBAAiB,GAAG,IAAAC,wBAAgB,EAACH,QAAQ,EAAE,UAAU,EAAED,QAAQ,CAAC;EAE1E,MAAM;IAAEP,QAAQ;IAAEG;EAAO,CAAC,GAAGO,iBAAiB,GAC1CX,oBAAoB,CAAC,CAAC,GACtBK,aAAa,CAAC,CAAC;EACnB,MAAMd,WAAW,GAAGF,iBAAiB,CACnCe,MAAM,EACNM,eAAe,CACb;IACEG,UAAU,EAAEL,QAAQ;IACpB,GAAGlB;EACL,CAAC,EACDkB,QACF,CACF,CAAC;EAED,MAAMrB,OAAO,GAAGnC,EAAE,CAAC8D,aAAa,CAACvB,WAAW,CAAC;EAE7C,OAAO;IACLJ,OAAO;IACPc;EACF,CAAC;AACH"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wyw-in-js/transform",
3
- "version": "0.5.4",
3
+ "version": "0.6.0",
4
4
  "dependencies": {
5
5
  "@babel/core": "^7.23.5",
6
6
  "@babel/generator": "^7.23.5",
@@ -11,12 +11,12 @@
11
11
  "@babel/types": "^7.23.5",
12
12
  "babel-merge": "^3.0.0",
13
13
  "cosmiconfig": "^8.0.0",
14
- "happy-dom": "^12.5.0",
14
+ "happy-dom": "^15.11.0",
15
15
  "source-map": "^0.7.4",
16
16
  "stylis": "^4.3.0",
17
17
  "ts-invariant": "^0.10.3",
18
- "@wyw-in-js/processor-utils": "0.5.4",
19
- "@wyw-in-js/shared": "0.5.4"
18
+ "@wyw-in-js/processor-utils": "0.6.0",
19
+ "@wyw-in-js/shared": "0.6.0"
20
20
  },
21
21
  "devDependencies": {
22
22
  "@babel/plugin-syntax-typescript": "^7.23.3",
@@ -37,10 +37,10 @@
37
37
  "glob": "^10.3.10",
38
38
  "strip-ansi": "^5.2.0",
39
39
  "typescript": "^5.2.2",
40
- "@wyw-in-js/babel-config": "0.5.4",
41
- "@wyw-in-js/eslint-config": "0.5.4",
42
- "@wyw-in-js/jest-preset": "0.5.4",
43
- "@wyw-in-js/ts-config": "0.5.4"
40
+ "@wyw-in-js/babel-config": "0.6.0",
41
+ "@wyw-in-js/eslint-config": "0.6.0",
42
+ "@wyw-in-js/jest-preset": "0.6.0",
43
+ "@wyw-in-js/ts-config": "0.6.0"
44
44
  },
45
45
  "engines": {
46
46
  "node": ">=16.0.0"
@@ -23,7 +23,15 @@ function dynamicImport(babel) {
23
23
  ]));
24
24
  return;
25
25
  }
26
- throw new Error('Dynamic import argument must be a string or a template literal');
26
+ // Throw an error if this import will be reached during evaluation
27
+ // throw new Error(
28
+ // 'Dynamic import argument must be a string or a template literal'
29
+ // );
30
+ path.replaceWith(t.callExpression(t.arrowFunctionExpression([], t.blockStatement([
31
+ t.throwStatement(t.newExpression(t.identifier('Error'), [
32
+ t.stringLiteral('Dynamic import argument must be a string or a template literal'),
33
+ ])),
34
+ ])), []));
27
35
  }
28
36
  },
29
37
  },
@@ -7,7 +7,7 @@ import type { StrictOptions } from '@wyw-in-js/shared';
7
7
  import type { Core } from '../babel';
8
8
  import type { IPluginState } from '../types';
9
9
  import { EventEmitter } from '../utils/EventEmitter';
10
- export type PreevalOptions = Pick<StrictOptions, 'classNameSlug' | 'displayName' | 'extensions' | 'evaluate' | 'features' | 'tagResolver'> & {
10
+ export type PreevalOptions = Pick<StrictOptions, 'classNameSlug' | 'codeRemover' | 'displayName' | 'extensions' | 'evaluate' | 'features' | 'tagResolver'> & {
11
11
  eventEmitter?: EventEmitter;
12
12
  };
13
13
  export declare function preeval(babel: Core, options: PreevalOptions): PluginObj<IPluginState & {
@@ -32,7 +32,7 @@ function preeval(babel, options) {
32
32
  });
33
33
  if ((0, shared_1.isFeatureEnabled)(options.features, 'dangerousCodeRemover', filename)) {
34
34
  log('start', 'Strip all JSX and browser related stuff');
35
- eventEmitter.perf('transform:preeval:removeDangerousCode', () => (0, removeDangerousCode_1.removeDangerousCode)(file.path));
35
+ eventEmitter.perf('transform:preeval:removeDangerousCode', () => (0, removeDangerousCode_1.removeDangerousCode)(file.path, options.codeRemover));
36
36
  }
37
37
  },
38
38
  visitor: {},
@@ -1,3 +1,4 @@
1
1
  import type { NodePath } from '@babel/core';
2
2
  import type { Program } from '@babel/types';
3
- export declare const removeDangerousCode: (programPath: NodePath<Program>) => void;
3
+ import type { CodeRemoverOptions } from '@wyw-in-js/shared';
4
+ export declare const removeDangerousCode: (programPath: NodePath<Program>, options?: CodeRemoverOptions) => void;
@@ -1,10 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.removeDangerousCode = void 0;
4
+ const core_1 = require("@babel/core");
4
5
  const findIdentifiers_1 = require("./findIdentifiers");
5
6
  const isUnnecessaryReactCall_1 = require("./isUnnecessaryReactCall");
6
7
  const scopeHelpers_1 = require("./scopeHelpers");
7
8
  const JSXElementsRemover_1 = require("./visitors/JSXElementsRemover");
9
+ const collectExportsAndImports_1 = require("./collectExportsAndImports");
8
10
  const isGlobal = (id) => {
9
11
  if (!(0, findIdentifiers_1.nonType)(id)) {
10
12
  return false;
@@ -49,7 +51,125 @@ const getPropertyName = (path) => {
49
51
  }
50
52
  return null;
51
53
  };
52
- const removeDangerousCode = (programPath) => {
54
+ const getImport = (path) => {
55
+ const programPath = path.findParent((p) => p.isProgram());
56
+ if (!programPath) {
57
+ return undefined;
58
+ }
59
+ const { imports } = (0, collectExportsAndImports_1.collectExportsAndImports)(programPath);
60
+ if (path.isIdentifier()) {
61
+ const binding = path.scope.getBinding(path.node.name);
62
+ const matched = binding &&
63
+ imports.find((imp) => imp.imported !== 'side-effect' && binding.path.isAncestor(imp.local));
64
+ if (matched) {
65
+ return [matched.source, matched.imported];
66
+ }
67
+ }
68
+ if (path.isMemberExpression()) {
69
+ const leftPath = path.get('object');
70
+ if (!leftPath.isIdentifier()) {
71
+ // Nested member expression. Not supported yet.
72
+ return undefined;
73
+ }
74
+ const rightPath = path.get('property');
75
+ if (!rightPath.isIdentifier()) {
76
+ return undefined;
77
+ }
78
+ const binding = path.scope.getBinding(leftPath.node.name);
79
+ const matched = binding &&
80
+ imports.find((imp) => imp.imported !== 'side-effect' && binding.path.isAncestor(imp.local));
81
+ if (matched) {
82
+ return [matched.source, rightPath.node.name];
83
+ }
84
+ }
85
+ return undefined;
86
+ };
87
+ const getTypeImport = (path) => {
88
+ // We are looking for either Identifier or TSQualifiedName in path
89
+ if (path.isIdentifier()) {
90
+ const binding = path.scope.getBinding(path.node.name);
91
+ if (!binding) {
92
+ return undefined;
93
+ }
94
+ if (!binding.path.isImportSpecifier() ||
95
+ !binding.path.parentPath.isImportDeclaration()) {
96
+ return undefined;
97
+ }
98
+ const importDeclaration = binding.path.parentPath;
99
+ const imported = binding.path.get('imported');
100
+ const source = importDeclaration.node.source.value;
101
+ const importedNode = imported.node;
102
+ return [
103
+ source,
104
+ core_1.types.isIdentifier(importedNode) ? importedNode.name : importedNode.value,
105
+ ];
106
+ }
107
+ if (path.isTSQualifiedName()) {
108
+ const leftPath = path.get('left');
109
+ if (!leftPath.isIdentifier()) {
110
+ // Nested type. Not supported yet.
111
+ return undefined;
112
+ }
113
+ const rightPath = path.get('right');
114
+ const binding = path.scope.getBinding(leftPath.node.name);
115
+ if (!binding) {
116
+ return undefined;
117
+ }
118
+ if ((!binding.path.isImportDefaultSpecifier() &&
119
+ !binding.path.isImportNamespaceSpecifier()) ||
120
+ !binding.path.parentPath.isImportDeclaration()) {
121
+ return undefined;
122
+ }
123
+ return [binding.path.parentPath.node.source.value, rightPath.node.name];
124
+ }
125
+ return undefined;
126
+ };
127
+ const isTypeMatch = (id, types) => {
128
+ const typeAnnotation = id.get('typeAnnotation');
129
+ if (!typeAnnotation.isTSTypeAnnotation()) {
130
+ return false;
131
+ }
132
+ const typeReference = typeAnnotation.get('typeAnnotation');
133
+ if (!typeReference.isTSTypeReference()) {
134
+ return false;
135
+ }
136
+ const typeName = typeReference.get('typeName');
137
+ const matchedImport = getTypeImport(typeName);
138
+ return (matchedImport !== undefined &&
139
+ matchedImport[0] in types &&
140
+ types[matchedImport[0]].includes(matchedImport[1]));
141
+ };
142
+ const isHOC = (path, hocs) => {
143
+ let calleePath = path;
144
+ while (calleePath.isCallExpression()) {
145
+ calleePath = calleePath.get('callee');
146
+ }
147
+ const matchedImport = getImport(calleePath);
148
+ return (matchedImport !== undefined &&
149
+ matchedImport[0] in hocs &&
150
+ hocs[matchedImport[0]].includes(matchedImport[1]));
151
+ };
152
+ const defaultPlaceholder = '...';
153
+ const defaultReactComponentTypes = [
154
+ 'ExoticComponent',
155
+ 'FC',
156
+ 'ForwardRefExoticComponent',
157
+ 'FunctionComponent',
158
+ 'LazyExoticComponent',
159
+ 'MemoExoticComponent',
160
+ 'NamedExoticComponent',
161
+ ];
162
+ const removeDangerousCode = (programPath, options) => {
163
+ const hocs = options?.hocs ?? {};
164
+ const componentTypes = options?.componentTypes ?? {
165
+ react: [defaultPlaceholder],
166
+ };
167
+ if (Array.isArray(componentTypes.react) &&
168
+ componentTypes.react.includes(defaultPlaceholder)) {
169
+ const idx = componentTypes.react.indexOf(defaultPlaceholder);
170
+ componentTypes.react = [...componentTypes.react];
171
+ componentTypes.react.splice(idx, 1, ...defaultReactComponentTypes);
172
+ }
53
173
  programPath.traverse({
54
174
  // JSX can be replaced with a dummy value,
55
175
  // but we have to do it after we processed template tags.
@@ -58,6 +178,13 @@ const removeDangerousCode = (programPath) => {
58
178
  if ((0, isUnnecessaryReactCall_1.isUnnecessaryReactCall)(p)) {
59
179
  (0, JSXElementsRemover_1.JSXElementsRemover)(p);
60
180
  }
181
+ if (isHOC(p, hocs)) {
182
+ (0, scopeHelpers_1.applyAction)([
183
+ 'replace',
184
+ p,
185
+ core_1.types.arrowFunctionExpression([], core_1.types.nullLiteral()),
186
+ ]);
187
+ }
61
188
  },
62
189
  },
63
190
  JSXElement: {
@@ -136,6 +263,20 @@ const removeDangerousCode = (programPath) => {
136
263
  { type: 'StringLiteral', value: 'undefined' },
137
264
  ]);
138
265
  },
266
+ VariableDeclarator(p) {
267
+ const id = p.get('id');
268
+ const init = p.get('init');
269
+ if (id.isIdentifier() &&
270
+ isTypeMatch(id, componentTypes) &&
271
+ init.isExpression()) {
272
+ // Variable is typed as a React component. We can replace its value with a null-function.
273
+ (0, scopeHelpers_1.applyAction)([
274
+ 'replace',
275
+ init,
276
+ core_1.types.arrowFunctionExpression([], core_1.types.nullLiteral()),
277
+ ]);
278
+ }
279
+ },
139
280
  }, {
140
281
  globals: [],
141
282
  windowScoped: new Set(),
@@ -1,5 +1,4 @@
1
1
  import type { NodePath } from '@babel/traverse';
2
2
  import type { Node } from '@babel/types';
3
3
  export declare const getTraversalCache: <TValue, TKey extends Node | NodePath<Node> = NodePath<Node>>(path: NodePath, name: string) => WeakMap<TKey, TValue>;
4
- export declare const clearBabelTraversalCache: () => void;
5
4
  export declare const invalidateTraversalCache: (path: NodePath) => void;
@@ -1,10 +1,6 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.invalidateTraversalCache = exports.clearBabelTraversalCache = exports.getTraversalCache = void 0;
7
- const traverse_1 = __importDefault(require("@babel/traverse"));
3
+ exports.invalidateTraversalCache = exports.getTraversalCache = void 0;
8
4
  const caches = new WeakMap();
9
5
  const getTraversalCache = (path, name) => {
10
6
  const programPath = path.find((p) => p.isProgram());
@@ -21,11 +17,6 @@ const getTraversalCache = (path, name) => {
21
17
  return cache.get(name);
22
18
  };
23
19
  exports.getTraversalCache = getTraversalCache;
24
- const traverseCache = traverse_1.default.cache;
25
- const clearBabelTraversalCache = () => {
26
- traverseCache.clear();
27
- };
28
- exports.clearBabelTraversalCache = clearBabelTraversalCache;
29
20
  const invalidateTraversalCache = (path) => {
30
21
  const programPath = path.find((p) => p.isProgram());
31
22
  if (!programPath) {
@@ -37,14 +37,24 @@ function createWindow() {
37
37
  win.Uint8Array = Uint8Array;
38
38
  return win;
39
39
  }
40
+ /**
41
+ * `happy-dom` already has required references, so we don't need to set them.
42
+ */
43
+ function setReferencePropertyIfNotPresent(context, key) {
44
+ if (context[key] === context) {
45
+ return;
46
+ }
47
+ context[key] = context;
48
+ }
40
49
  function createBaseContext(win, additionalContext) {
41
50
  const baseContext = win ?? {};
51
+ setReferencePropertyIfNotPresent(baseContext, 'window');
52
+ setReferencePropertyIfNotPresent(baseContext, 'self');
53
+ setReferencePropertyIfNotPresent(baseContext, 'top');
54
+ setReferencePropertyIfNotPresent(baseContext, 'parent');
55
+ setReferencePropertyIfNotPresent(baseContext, 'global');
56
+ setReferencePropertyIfNotPresent(baseContext, 'process');
42
57
  baseContext.document = win?.document;
43
- baseContext.window = win;
44
- baseContext.self = win;
45
- baseContext.top = win;
46
- baseContext.parent = win;
47
- baseContext.global = win;
48
58
  baseContext.process = process;
49
59
  baseContext.clearImmediate = NOOP;
50
60
  baseContext.clearInterval = NOOP;
@@ -63,7 +73,7 @@ function createHappyDOMWindow() {
63
73
  const win = createWindow();
64
74
  return {
65
75
  teardown: () => {
66
- win.happyDOM.cancelAsync();
76
+ win.happyDOM.abort();
67
77
  },
68
78
  window: win,
69
79
  };