@agilebot/eslint-plugin 0.1.2 → 0.1.4

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.
package/lib/index.js CHANGED
@@ -1,52 +1,59 @@
1
- // @ts-check
2
- const path = require('path');
3
- const { globSync } = require('fast-glob');
4
-
5
- // List all rules in rules folder
6
- const rulesPath = path.join(__dirname, 'rules');
7
- const ruleFiles = globSync('**/*.js', {
8
- cwd: rulesPath
9
- });
10
- const rules = {};
11
- ruleFiles.forEach(file => {
12
- const { dir, name } = path.parse(file);
13
- const ruleName = `${dir}/${name}`;
14
- rules[ruleName] = require(path.join(rulesPath, file));
15
- });
16
-
17
- module.exports.rules = rules;
18
-
19
- module.exports.configs = {
20
- recommended: {
21
- plugins: ['@agilebot'],
22
- rules: {
23
- 'react-hooks/exhaustive-deps': 'off',
24
- '@agilebot/react/better-exhaustive-deps': [
25
- 'warn',
26
- {
27
- checkMemoizedVariableIsStatic: true,
28
- staticHooks: {
29
- useIpcSender: true,
30
- useDialog: true,
31
- useSnackbar: true,
32
- useForm: true,
33
- 'use.*Store': {
34
- value: true,
35
- regexp: true
36
- }
37
- }
38
- }
39
- ],
40
- '@agilebot/react/prefer-named-property-access': 'error',
41
- '@agilebot/react/hook-use-ref': 'warn',
42
- '@agilebot/react/no-inline-styles': 'error',
43
- '@agilebot/tss/unused-classes': 'warn',
44
- '@agilebot/tss/no-color-value': 'error',
45
- '@agilebot/tss/class-naming': 'error',
46
- '@agilebot/import/enforce-icon-alias': 'error',
47
- '@agilebot/import/monorepo': 'error',
48
- '@agilebot/others/no-unnecessary-template-literals': 'error'
49
- },
50
- settings: {}
51
- }
52
- };
1
+ // @ts-check
2
+ const path = require('node:path');
3
+ const { globSync } = require('fast-glob');
4
+
5
+ // List all rules in rules folder
6
+ const rulesPath = path.join(__dirname, 'rules');
7
+ const ruleFiles = globSync('**/*.js', {
8
+ cwd: rulesPath
9
+ });
10
+
11
+ /**
12
+ * @type {import('eslint').Linter.RulesRecord}
13
+ */
14
+ const rules = {};
15
+ ruleFiles.forEach(file => {
16
+ const { dir, name } = path.parse(file);
17
+ const ruleName = `${dir}/${name}`;
18
+ rules[ruleName] = require(path.join(rulesPath, file));
19
+ });
20
+
21
+ module.exports.rules = rules;
22
+
23
+ module.exports.configs = {
24
+ recommended: {
25
+ plugins: ['@agilebot'],
26
+ rules: {
27
+ 'react-hooks/exhaustive-deps': 'off',
28
+ '@agilebot/react/better-exhaustive-deps': [
29
+ 'warn',
30
+ {
31
+ checkMemoizedVariableIsStatic: true,
32
+ staticHooks: {
33
+ 'useIpc.*': {
34
+ value: true,
35
+ regexp: true
36
+ },
37
+ useDialog: true,
38
+ useSnackbar: true,
39
+ useForm: true,
40
+ 'use.*Store': {
41
+ value: true,
42
+ regexp: true
43
+ }
44
+ }
45
+ }
46
+ ],
47
+ '@agilebot/react/prefer-named-property-access': 'error',
48
+ '@agilebot/react/hook-use-ref': 'warn',
49
+ '@agilebot/react/no-inline-styles': 'error',
50
+ '@agilebot/tss/unused-classes': 'warn',
51
+ '@agilebot/tss/no-color-value': 'error',
52
+ '@agilebot/tss/class-naming': 'error',
53
+ '@agilebot/import/enforce-icon-alias': 'error',
54
+ '@agilebot/import/monorepo': 'error',
55
+ '@agilebot/others/no-unnecessary-template-literals': 'error'
56
+ },
57
+ settings: {}
58
+ }
59
+ };
@@ -1,6 +1,7 @@
1
- const { consola } = require('consola');
2
1
  const { getSetting } = require('../../util/settings');
3
2
 
3
+ let warnedForMissingPrefix = false;
4
+
4
5
  module.exports = {
5
6
  meta: {
6
7
  type: 'problem', // `problem`, `suggestion`, or `layout`
@@ -17,7 +18,11 @@ module.exports = {
17
18
  ImportDeclaration(node) {
18
19
  const prefix = getSetting(context, 'monorepo-prefix');
19
20
  if (!prefix) {
20
- consola.warn('agilebot/monorepo-prefix is not set');
21
+ if (!warnedForMissingPrefix) {
22
+ // eslint-disable-next-line no-console -- this is a CLI tool
23
+ console.error('Warning: agilebot/monorepo-prefix is not set.');
24
+ warnedForMissingPrefix = true;
25
+ }
21
26
  return;
22
27
  }
23
28
 
@@ -1,5 +1,5 @@
1
- const path = require('path');
2
- const fs = require('fs');
1
+ const path = require('node:path');
2
+ const fs = require('node:fs');
3
3
  const {
4
4
  sortedTemplateElements,
5
5
  findFormatMessageAttrNode,
@@ -1,6 +1,3 @@
1
- /* eslint-disable no-case-declarations */
2
- /* eslint-disable no-continue */
3
-
4
1
  /**
5
2
  * Copyright (c) Facebook, Inc. and its affiliates.
6
3
  *
@@ -96,12 +93,13 @@ module.exports = {
96
93
  };
97
94
 
98
95
  function reportProblem(problem) {
99
- if (enableDangerousAutofixThisMayCauseInfiniteLoops) {
100
- // Used to enable legacy behavior. Dangerous.
96
+ if (
97
+ enableDangerousAutofixThisMayCauseInfiniteLoops && // Used to enable legacy behavior. Dangerous.
101
98
  // Keep this as an option until major IDEs upgrade (including VSCode FB ESLint extension).
102
- if (Array.isArray(problem.suggest) && problem.suggest.length > 0) {
103
- problem.fix = problem.suggest[0].fix;
104
- }
99
+ Array.isArray(problem.suggest) &&
100
+ problem.suggest.length > 0
101
+ ) {
102
+ problem.fix = problem.suggest[0].fix;
105
103
  }
106
104
  context.report(problem);
107
105
  }
@@ -286,17 +284,14 @@ module.exports = {
286
284
  if (name === 'useState') {
287
285
  const references = resolved.references;
288
286
  let writeCount = 0;
289
- for (let i = 0; i < references.length; i++) {
290
- if (references[i].isWrite()) {
287
+ for (const reference of references) {
288
+ if (reference.isWrite()) {
291
289
  writeCount++;
292
290
  }
293
291
  if (writeCount > 1) {
294
292
  return false;
295
293
  }
296
- setStateCallSites.set(
297
- references[i].identifier,
298
- id.elements[0]
299
- );
294
+ setStateCallSites.set(reference.identifier, id.elements[0]);
300
295
  }
301
296
  }
302
297
  // Setter is stable.
@@ -304,8 +299,8 @@ module.exports = {
304
299
  } else if (id.elements[0] === resolved.identifiers[0]) {
305
300
  if (name === 'useState') {
306
301
  const references = resolved.references;
307
- for (let i = 0; i < references.length; i++) {
308
- stateVariables.add(references[i].identifier);
302
+ for (const reference of references) {
303
+ stateVariables.add(reference.identifier);
309
304
  }
310
305
  }
311
306
  // State variable itself is dynamic.
@@ -317,13 +312,11 @@ module.exports = {
317
312
  if (
318
313
  id.type === 'ArrayPattern' &&
319
314
  id.elements.length === 2 &&
320
- Array.isArray(resolved.identifiers)
315
+ Array.isArray(resolved.identifiers) && // Is second tuple value the same reference we're checking?
316
+ id.elements[1] === resolved.identifiers[0]
321
317
  ) {
322
- // Is second tuple value the same reference we're checking?
323
- if (id.elements[1] === resolved.identifiers[0]) {
324
- // Setter is stable.
325
- return true;
326
- }
318
+ // Setter is stable.
319
+ return true;
327
320
  }
328
321
  } else if (
329
322
  options.checkMemoizedVariableIsStatic &&
@@ -350,7 +343,7 @@ module.exports = {
350
343
  );
351
344
 
352
345
  if (
353
- typeof dependencyRefernece !== 'undefined' &&
346
+ dependencyRefernece !== undefined &&
354
347
  memoizedIsStableKnownHookValue(dependencyRefernece.resolved)
355
348
  ) {
356
349
  continue;
@@ -372,7 +365,6 @@ module.exports = {
372
365
  }
373
366
  });
374
367
 
375
- // eslint-disable-next-line no-lonely-if
376
368
  if (options.staticHooks[name]) {
377
369
  const staticParts = options.staticHooks[name];
378
370
  if (staticParts === true) {
@@ -386,9 +378,7 @@ module.exports = {
386
378
  Array.isArray(resolved.identifiers)
387
379
  ) {
388
380
  // find index of the resolved ident in the array pattern
389
- const idx = id.elements.findIndex(
390
- ident => ident === resolved.identifiers[0]
391
- );
381
+ const idx = id.elements.indexOf(resolved.identifiers[0]);
392
382
  if (idx >= 0) {
393
383
  return staticParts[idx];
394
384
  }
@@ -587,8 +577,7 @@ module.exports = {
587
577
  // Is React managing this ref or us?
588
578
  // Let's see if we can find a .current assignment.
589
579
  let foundCurrentAssignment = false;
590
- for (let i = 0; i < references.length; i++) {
591
- const { identifier } = references[i];
580
+ for (const { identifier } of references) {
592
581
  const { parent } = identifier;
593
582
  if (
594
583
  parent != null &&
@@ -764,8 +753,8 @@ module.exports = {
764
753
  declaredDependencyNode,
765
754
  null
766
755
  );
767
- } catch (error) {
768
- if (/Unsupported node type/.test(error.message)) {
756
+ } catch (err) {
757
+ if (/Unsupported node type/.test(err.message)) {
769
758
  if (declaredDependencyNode.type === 'Literal') {
770
759
  if (dependencies.has(declaredDependencyNode.value)) {
771
760
  reportProblem({
@@ -795,7 +784,7 @@ module.exports = {
795
784
 
796
785
  return;
797
786
  }
798
- throw error;
787
+ throw err;
799
788
  }
800
789
 
801
790
  let maybeID = declaredDependencyNode;
@@ -942,7 +931,7 @@ module.exports = {
942
931
  return true;
943
932
  }
944
933
  const declaredDepKeys = declaredDependencies.map(dep => dep.key);
945
- const sortedDeclaredDepKeys = declaredDepKeys.slice().sort();
934
+ const sortedDeclaredDepKeys = [...declaredDepKeys].sort();
946
935
  return declaredDepKeys.join(',') === sortedDeclaredDepKeys.join(',');
947
936
  }
948
937
  if (areDeclaredDepsAlphabetized()) {
@@ -978,9 +967,7 @@ module.exports = {
978
967
  (deps.size > 1 ? 'dependencies' : 'dependency') +
979
968
  ': ' +
980
969
  joinEnglish(
981
- Array.from(deps)
982
- .sort()
983
- .map(name => "'" + formatDependency(name) + "'")
970
+ [...deps].sort().map(name => "'" + formatDependency(name) + "'")
984
971
  ) +
985
972
  `. Either ${fixVerb} ${
986
973
  deps.size > 1 ? 'them' : 'it'
@@ -991,7 +978,7 @@ module.exports = {
991
978
  let extraWarning = '';
992
979
  if (unnecessaryDependencies.size > 0) {
993
980
  let badRef = null;
994
- Array.from(unnecessaryDependencies.keys()).forEach(key => {
981
+ [...unnecessaryDependencies.keys()].forEach(key => {
995
982
  if (badRef != null) {
996
983
  return;
997
984
  }
@@ -1004,7 +991,7 @@ module.exports = {
1004
991
  ` Mutable values like '${badRef}' aren't valid dependencies ` +
1005
992
  "because mutating them doesn't re-render the component.";
1006
993
  } else if (externalDependencies.size > 0) {
1007
- const dep = Array.from(externalDependencies)[0];
994
+ const dep = [...externalDependencies][0];
1008
995
  // Don't show this warning for things that likely just got moved *inside* the callback
1009
996
  // because in that case they're clearly not referring to globals.
1010
997
  if (!scope.set.has(dep)) {
@@ -1028,8 +1015,7 @@ module.exports = {
1028
1015
  return;
1029
1016
  }
1030
1017
  let isPropsOnlyUsedInMembers = true;
1031
- for (let i = 0; i < refs.length; i++) {
1032
- const ref = refs[i];
1018
+ for (const ref of refs) {
1033
1019
  const id = fastFindReferenceWithParent(
1034
1020
  componentScope.block,
1035
1021
  ref.identifier
@@ -1121,8 +1107,8 @@ module.exports = {
1121
1107
  const references = usedDep.references;
1122
1108
  let id;
1123
1109
  let maybeCall;
1124
- for (let i = 0; i < references.length; i++) {
1125
- id = references[i].identifier;
1110
+ for (const reference of references) {
1111
+ id = reference.identifier;
1126
1112
  maybeCall = id.parent;
1127
1113
  // Try to see if we have setState(someExpr(missingDep)).
1128
1114
  while (maybeCall != null && maybeCall !== componentScope.block) {
@@ -1146,7 +1132,7 @@ module.exports = {
1146
1132
  form: 'reducer'
1147
1133
  };
1148
1134
  } else {
1149
- const resolved = references[i].resolved;
1135
+ const resolved = reference.resolved;
1150
1136
  if (resolved != null) {
1151
1137
  // If it's a parameter *and* a missing dep,
1152
1138
  // it must be a prop or something inside a prop.
@@ -1189,7 +1175,7 @@ module.exports = {
1189
1175
  case 'updater':
1190
1176
  extraWarning = ` You can also do a functional update '${
1191
1177
  setStateRecommendation.setter
1192
- }(${setStateRecommendation.missingDep.substring(
1178
+ }(${setStateRecommendation.missingDep.slice(
1193
1179
  0,
1194
1180
  1
1195
1181
  )} => ...)' if you only need '${
@@ -1224,13 +1210,13 @@ module.exports = {
1224
1210
  suggest: [
1225
1211
  {
1226
1212
  desc: `Update the dependencies array to be: [${suggestedDeps
1227
- .map(formatDependency)
1213
+ .map(element => formatDependency(element))
1228
1214
  .join(', ')}]`,
1229
1215
  fix(fixer) {
1230
1216
  // TODO: consider preserving the comments or formatting?
1231
1217
  return fixer.replaceText(
1232
1218
  declaredDependenciesNode,
1233
- `[${suggestedDeps.map(formatDependency).join(', ')}]`
1219
+ `[${suggestedDeps.map(element => formatDependency(element)).join(', ')}]`
1234
1220
  );
1235
1221
  }
1236
1222
  }
@@ -1520,7 +1506,7 @@ function collectRecommendations({
1520
1506
  declaredDependencies.forEach(({ key }) => {
1521
1507
  // Does this declared dep satisfy a real need?
1522
1508
  if (satisfyingDependencies.has(key)) {
1523
- if (suggestedDependencies.indexOf(key) === -1) {
1509
+ if (!suggestedDependencies.includes(key)) {
1524
1510
  // Good one.
1525
1511
  suggestedDependencies.push(key);
1526
1512
  } else {
@@ -1536,7 +1522,7 @@ function collectRecommendations({
1536
1522
  // Such as resetting scroll when ID changes.
1537
1523
  // Consider them legit.
1538
1524
  // The exception is ref.current which is always wrong.
1539
- if (suggestedDependencies.indexOf(key) === -1) {
1525
+ if (!suggestedDependencies.includes(key)) {
1540
1526
  suggestedDependencies.push(key);
1541
1527
  }
1542
1528
  } else {
@@ -1681,12 +1667,12 @@ function scanForConstructions({
1681
1667
  while (currentScope !== scope && currentScope != null) {
1682
1668
  currentScope = currentScope.upper;
1683
1669
  }
1684
- if (currentScope !== scope) {
1685
- // This reference is outside the Hook callback.
1670
+ if (
1671
+ currentScope !== scope && // This reference is outside the Hook callback.
1686
1672
  // It can only be legit if it's the deps array.
1687
- if (!isAncestorNodeOf(declaredDependenciesNode, reference.identifier)) {
1688
- return true;
1689
- }
1673
+ !isAncestorNodeOf(declaredDependenciesNode, reference.identifier)
1674
+ ) {
1675
+ return true;
1690
1676
  }
1691
1677
  }
1692
1678
  return false;
@@ -1837,11 +1823,11 @@ function getReactiveHookCallbackIndex(calleeNode, options) {
1837
1823
  let name;
1838
1824
  try {
1839
1825
  name = analyzePropertyChain(node, null);
1840
- } catch (error) {
1841
- if (/Unsupported node type/.test(error.message)) {
1826
+ } catch (err) {
1827
+ if (/Unsupported node type/.test(err.message)) {
1842
1828
  return 0;
1843
1829
  }
1844
- throw error;
1830
+ throw err;
1845
1831
  }
1846
1832
  return options.additionalHooks.test(name) ? 0 : -1;
1847
1833
  }
@@ -1863,7 +1849,7 @@ function fastFindReferenceWithParent(start, target) {
1863
1849
  const queue = [start];
1864
1850
  let item = null;
1865
1851
 
1866
- while (queue.length) {
1852
+ while (queue.length > 0) {
1867
1853
  item = queue.shift();
1868
1854
 
1869
1855
  if (isSameIdentifier(item, target)) {
@@ -1882,7 +1868,7 @@ function fastFindReferenceWithParent(start, target) {
1882
1868
  value.parent = item;
1883
1869
  queue.push(value);
1884
1870
  } else if (Array.isArray(value)) {
1885
- // eslint-disable-next-line no-loop-func
1871
+ // eslint-disable-next-line no-loop-func -- FIXME
1886
1872
  value.forEach(val => {
1887
1873
  if (isNodeLike(val)) {
1888
1874
  val.parent = item;
@@ -40,7 +40,7 @@ function* updateImportStatement(context, fixer, key) {
40
40
  }
41
41
 
42
42
  // Named imports section is present and current key is not imported yet - add it to named imports section
43
- yield fixer.insertTextAfter(importNode.specifiers.slice().pop(), `, ${key}`);
43
+ yield fixer.insertTextAfter([...importNode.specifiers].pop(), `, ${key}`);
44
44
  }
45
45
 
46
46
  /** @type {import('eslint').Rule.RuleModule} */
@@ -9,7 +9,7 @@ module.exports = {
9
9
  CallExpression(node) {
10
10
  const stylesObj = getStyesObj(node);
11
11
 
12
- if (typeof stylesObj === 'undefined') {
12
+ if (stylesObj === undefined) {
13
13
  return;
14
14
  }
15
15
 
@@ -25,7 +25,6 @@ module.exports = {
25
25
  function checkColorLiteral(value) {
26
26
  if (value.type === 'Literal' && typeof value.value === 'string') {
27
27
  const colorCodePattern =
28
- // eslint-disable-next-line max-len
29
28
  /#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\?\(\s*(\d{1,3}\s*,\s*){2}\d{1,3}(?:\s*,\s*\d*(?:\.\d+)?)?\s*\)/g;
30
29
  const isColorCode = colorCodePattern.test(value.value);
31
30
  if (isColorCode) {
@@ -12,7 +12,7 @@ module.exports = {
12
12
  CallExpression(node) {
13
13
  const stylesObj = getStyesObj(node);
14
14
 
15
- if (typeof stylesObj === 'undefined') {
15
+ if (stylesObj === undefined) {
16
16
  return;
17
17
  }
18
18
 
package/lib/util/intl.js CHANGED
@@ -9,13 +9,13 @@ function findFormatMessageAttrNode(node, attrName) {
9
9
  // Find formatMessage usages
10
10
  if (
11
11
  node.type === 'CallExpression' &&
12
- (node.callee.name === 'formatMessage' || node.callee.name === '$t')
12
+ (node.callee.name === 'formatMessage' || node.callee.name === '$t') &&
13
+ node.arguments.length > 0 &&
14
+ node.arguments[0].properties
13
15
  ) {
14
- if (node.arguments.length && node.arguments[0].properties) {
15
- return node.arguments[0].properties.find(
16
- a => a.key && a.key.name === attrName
17
- );
18
- }
16
+ return node.arguments[0].properties.find(
17
+ a => a.key && a.key.name === attrName
18
+ );
19
19
  }
20
20
 
21
21
  // Find intl.formatMessage usages
@@ -1,7 +1,6 @@
1
- /* eslint-disable no-sync */
2
- const fs = require('fs');
3
- const path = require('path');
4
- const { tsImport } = require('./import');
1
+ const fs = require('node:fs');
2
+ const path = require('node:path');
3
+ const { tsImport } = require('@agilebot/eslint-utils');
5
4
  const { getSetting } = require('./settings');
6
5
 
7
6
  /**
package/lib/util/tss.js CHANGED
@@ -12,7 +12,7 @@ function getBasicIdentifier(node) {
12
12
 
13
13
  if (node.type === 'TemplateLiteral') {
14
14
  // Handle template literals, e.g., classes[`foo`]
15
- if (node.expressions.length) {
15
+ if (node.expressions.length > 0) {
16
16
  // Template literals with expressions, e.g., classes[`foo${bar}`]
17
17
  return null;
18
18
  }
@@ -25,12 +25,17 @@ function getBasicIdentifier(node) {
25
25
 
26
26
  // Helper function to recursively get the base identifier from a MemberExpression node
27
27
  function getBaseIdentifier(node) {
28
- if (node.type === 'Identifier') {
29
- return node;
30
- } else if (node.type === 'CallExpression') {
31
- return getBaseIdentifier(node.callee);
32
- } else if (node.type === 'MemberExpression') {
33
- return getBaseIdentifier(node.object);
28
+ switch (node.type) {
29
+ case 'Identifier': {
30
+ return node;
31
+ }
32
+ case 'CallExpression': {
33
+ return getBaseIdentifier(node.callee);
34
+ }
35
+ case 'MemberExpression': {
36
+ return getBaseIdentifier(node.object);
37
+ }
38
+ // No default
34
39
  }
35
40
  return null;
36
41
  }
package/package.json CHANGED
@@ -1,21 +1,27 @@
1
1
  {
2
2
  "name": "@agilebot/eslint-plugin",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Agilebot's ESLint plugin",
5
5
  "main": "lib",
6
6
  "license": "MIT",
7
+ "keywords": [
8
+ "eslint",
9
+ "eslint-plugin"
10
+ ],
7
11
  "repository": {
8
12
  "url": "sh-agilebot/frontend-toolkit",
9
13
  "directory": "packages/eslint-plugin"
10
14
  },
11
15
  "homepage": "https://github.com/sh-agilebot/frontend-toolkit/tree/master/packages/eslint-plugin#readme",
16
+ "engines": {
17
+ "node": "^18.18.0 || >=20.0.0"
18
+ },
12
19
  "dependencies": {
13
20
  "@typescript-eslint/utils": "^7.1.1",
14
- "consola": "^3.2.3",
15
- "fast-glob": "^3.3.2",
16
- "get-tsconfig": "^4.7.3",
17
- "jiti": "^1.21.0",
18
- "sucrase": "^3.35.0"
21
+ "fast-glob": "^3.3.2"
22
+ },
23
+ "peerDependencies": {
24
+ "eslint": "^7.0.0 || ^8.0.0"
19
25
  },
20
26
  "files": [
21
27
  "lib"
@@ -1,71 +0,0 @@
1
- const path = require('path');
2
- const jiti = require('jiti');
3
- const { transform } = require('sucrase');
4
- const { getTsconfig } = require('get-tsconfig');
5
-
6
- /**
7
- * import ts module, like require, but support ts
8
- * @param {*} modulePath - module path
9
- */
10
- function tsImport(modulePath) {
11
- if (!modulePath) {
12
- return;
13
- }
14
- /** try to delete cache first */
15
- try {
16
- if (require.cache[modulePath]) {
17
- delete require.cache[modulePath];
18
- }
19
- } catch (err) {
20
- /* empty */
21
- }
22
-
23
- try {
24
- return require(modulePath);
25
- } catch (err) {
26
- const tsconfig = getTsconfig(modulePath);
27
- const { paths, baseUrl } = tsconfig.config.compilerOptions;
28
- let basePath = path.dirname(tsconfig.path);
29
- basePath = path.resolve(basePath, baseUrl);
30
-
31
- const alias = resolveTsconfigPathsToAlias(paths, basePath);
32
-
33
- return jiti(__filename, {
34
- interopDefault: true,
35
- cache: false,
36
- debug: !!process.env.DEBUG,
37
- transform: options => {
38
- return transform(options.source, {
39
- transforms: ['imports', 'typescript']
40
- });
41
- },
42
- alias
43
- })(modulePath);
44
- }
45
- }
46
-
47
- /**
48
- * Resolve tsconfig.json paths to Webpack aliases
49
- * @param {string} paths - tsconfig.json paths
50
- * @param {string} basePath - Path from tsconfig to Webpack config to create absolute aliases
51
- * @return {object} - Webpack alias config
52
- */
53
- function resolveTsconfigPathsToAlias(paths, basePath = __dirname) {
54
- const aliases = {};
55
-
56
- Object.keys(paths).forEach(item => {
57
- const key = item.replace('/*', '');
58
- const value = path.resolve(
59
- basePath,
60
- paths[item][0].replace('/*', '').replace('*', '')
61
- );
62
-
63
- aliases[key] = value;
64
- });
65
-
66
- return aliases;
67
- }
68
-
69
- module.exports = {
70
- tsImport
71
- };