eslint-plugin-absolute 0.2.1 → 0.2.2

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/dist/index.js CHANGED
@@ -186,6 +186,75 @@ var explicitObjectTypes = {
186
186
 
187
187
  // src/rules/sort-keys-fixable.ts
188
188
  var SORT_BEFORE = -1;
189
+ var hasDuplicateNames = (names) => {
190
+ const seen = new Set;
191
+ const nonNullNames = names.flatMap((name) => name === null ? [] : [name]);
192
+ for (const name of nonNullNames) {
193
+ if (seen.has(name)) {
194
+ return true;
195
+ }
196
+ seen.add(name);
197
+ }
198
+ return false;
199
+ };
200
+ var isSafeStaticTemplate = (node) => node.expressions.length === 0;
201
+ var isSafeArrayElement = (node) => {
202
+ if (!node || node.type === "SpreadElement") {
203
+ return false;
204
+ }
205
+ return isSafeToReorderExpression(node);
206
+ };
207
+ var isSafeObjectProperty = (property) => {
208
+ if (property.type !== "Property" || property.computed || property.kind !== "init") {
209
+ return false;
210
+ }
211
+ if (property.key.type !== "Identifier" && property.key.type !== "Literal") {
212
+ return false;
213
+ }
214
+ if (property.method) {
215
+ return true;
216
+ }
217
+ return isSafeToReorderExpression(property.value);
218
+ };
219
+ var isSafeToReorderExpression = (node) => {
220
+ if (!node || node.type === "PrivateIdentifier") {
221
+ return false;
222
+ }
223
+ switch (node.type) {
224
+ case "Identifier":
225
+ case "Literal":
226
+ case "ThisExpression":
227
+ case "FunctionExpression":
228
+ case "ArrowFunctionExpression":
229
+ case "ClassExpression":
230
+ return true;
231
+ case "TemplateLiteral":
232
+ return isSafeStaticTemplate(node);
233
+ case "UnaryExpression":
234
+ return isSafeToReorderExpression(node.argument);
235
+ case "ArrayExpression":
236
+ return node.elements.every(isSafeArrayElement);
237
+ case "ObjectExpression":
238
+ return node.properties.every(isSafeObjectProperty);
239
+ default:
240
+ return false;
241
+ }
242
+ };
243
+ var isSafeJSXAttributeValue = (value) => {
244
+ if (value === null) {
245
+ return true;
246
+ }
247
+ if (value.type === "Literal") {
248
+ return true;
249
+ }
250
+ if (value.type !== "JSXExpressionContainer") {
251
+ return false;
252
+ }
253
+ if (value.expression.type === "JSXEmptyExpression") {
254
+ return false;
255
+ }
256
+ return isSafeToReorderExpression(value.expression);
257
+ };
189
258
  var sortKeysFixable = {
190
259
  create(context) {
191
260
  const { sourceCode } = context;
@@ -352,6 +421,12 @@ ${indent}`;
352
421
  node: prop
353
422
  };
354
423
  });
424
+ if (hasDuplicateNames(keys.map((key) => key.keyName))) {
425
+ autoFixable = false;
426
+ }
427
+ if (autoFixable && keys.some((key) => key.node.type === "Property" && !isSafeToReorderExpression(key.node.value))) {
428
+ autoFixable = false;
429
+ }
355
430
  let fixProvided = false;
356
431
  const createReportWithFix = (curr, shouldFix) => {
357
432
  context.report({
@@ -441,6 +516,20 @@ ${indent}`;
441
516
  if (!isOutOfOrder(names)) {
442
517
  return;
443
518
  }
519
+ if (hasDuplicateNames(names)) {
520
+ context.report({
521
+ messageId: "unsorted",
522
+ node: attrs[0].type === "JSXAttribute" ? attrs[0].name : attrs[0]
523
+ });
524
+ return;
525
+ }
526
+ if (attrs.some((attr) => attr.type === "JSXAttribute" && !isSafeJSXAttributeValue(attr.value))) {
527
+ context.report({
528
+ messageId: "unsorted",
529
+ node: attrs[0].type === "JSXAttribute" ? attrs[0].name : attrs[0]
530
+ });
531
+ return;
532
+ }
444
533
  const braceConflict = attrs.find((currAttr, idx) => {
445
534
  if (idx === 0) {
446
535
  return false;
@@ -797,7 +886,26 @@ var noUnnecessaryKey = {
797
886
  };
798
887
 
799
888
  // src/rules/sort-exports.ts
800
- var SORT_BEFORE2 = -1;
889
+ var SORT_BEFORE2 = Number.parseInt("-1", 10);
890
+ var hasStringTypeProperty = (value) => {
891
+ const maybeType = Reflect.get(value, "type");
892
+ return typeof maybeType === "string";
893
+ };
894
+ var isNodeLike = (value) => value !== null && value !== undefined && typeof value === "object" && ("type" in value) && hasStringTypeProperty(value);
895
+ var shouldSkipNodeEntry = (key, value) => key === "parent" || value === null || value === undefined;
896
+ var visitNodeArray = (values, visit) => values.filter(isNodeLike).forEach(visit);
897
+ var visitNodeEntryValue = (value, visit) => {
898
+ if (Array.isArray(value)) {
899
+ visitNodeArray(value, visit);
900
+ return;
901
+ }
902
+ if (isNodeLike(value)) {
903
+ visit(value);
904
+ }
905
+ };
906
+ var visitNodeEntries = (current, visit) => Object.entries(current).filter(([key, value]) => !shouldSkipNodeEntry(key, value)).forEach(([, value]) => {
907
+ visitNodeEntryValue(value, visit);
908
+ });
801
909
  var getVariableDeclaratorName = (declaration) => {
802
910
  if (declaration.declarations.length !== 1) {
803
911
  return null;
@@ -848,6 +956,76 @@ var isFixableExport = (exportNode) => {
848
956
  }
849
957
  return (declaration.type === "FunctionDeclaration" || declaration.type === "ClassDeclaration") && declaration.id !== null && declaration.id.type === "Identifier";
850
958
  };
959
+ var visitImmediateReferences = (node, onReference) => {
960
+ if (!node) {
961
+ return;
962
+ }
963
+ const visit = (current) => {
964
+ if (!current) {
965
+ return;
966
+ }
967
+ switch (current.type) {
968
+ case "Identifier":
969
+ onReference(current.name);
970
+ return;
971
+ case "FunctionDeclaration":
972
+ case "FunctionExpression":
973
+ case "ArrowFunctionExpression":
974
+ return;
975
+ case "MemberExpression":
976
+ visit(current.object);
977
+ if (current.computed) {
978
+ visit(current.property);
979
+ }
980
+ return;
981
+ case "Property":
982
+ if (current.computed) {
983
+ visit(current.key);
984
+ }
985
+ visit(current.value);
986
+ return;
987
+ case "PropertyDefinition":
988
+ if (current.computed) {
989
+ visit(current.key);
990
+ }
991
+ if (current.static) {
992
+ visit(current.value);
993
+ }
994
+ return;
995
+ case "MethodDefinition":
996
+ if (current.computed) {
997
+ visit(current.key);
998
+ }
999
+ return;
1000
+ case "StaticBlock":
1001
+ for (const statement of current.body) {
1002
+ visit(statement);
1003
+ }
1004
+ return;
1005
+ }
1006
+ visitNodeEntries(current, visit);
1007
+ };
1008
+ visit(node);
1009
+ };
1010
+ var getImmediateDependencyNames = (node) => {
1011
+ const names = new Set;
1012
+ const { declaration } = node;
1013
+ const addName = names.add.bind(names);
1014
+ const addDeclaratorDependencies = (declarator) => visitImmediateReferences(declarator.init, addName);
1015
+ const addClassElementDependencies = (element) => visitImmediateReferences(element, addName);
1016
+ if (!declaration) {
1017
+ return names;
1018
+ }
1019
+ if (declaration.type === "VariableDeclaration") {
1020
+ declaration.declarations.forEach(addDeclaratorDependencies);
1021
+ return names;
1022
+ }
1023
+ if (declaration.type === "ClassDeclaration") {
1024
+ visitImmediateReferences(declaration.superClass, addName);
1025
+ declaration.body.body.forEach(addClassElementDependencies);
1026
+ }
1027
+ return names;
1028
+ };
851
1029
  var sortExports = {
852
1030
  create(context) {
853
1031
  const { sourceCode } = context;
@@ -903,15 +1081,6 @@ var sortExports = {
903
1081
  }
904
1082
  return compareStrings(left.name, right.name);
905
1083
  };
906
- const hasForwardDependency = (node, laterNames) => {
907
- const text = sourceCode.getText(node);
908
- for (const name of laterNames) {
909
- if (text.includes(name)) {
910
- return true;
911
- }
912
- }
913
- return false;
914
- };
915
1084
  const buildItems = (block) => block.map((node) => {
916
1085
  const name = getExportName(node);
917
1086
  if (!name) {
@@ -949,8 +1118,16 @@ var sortExports = {
949
1118
  const exportNames = items.map((item) => item.name);
950
1119
  return items.some((item, idx) => {
951
1120
  const laterNames = new Set(exportNames.slice(idx + 1));
952
- const nodeToCheck = item.node.declaration ?? item.node;
953
- return hasForwardDependency(nodeToCheck, laterNames);
1121
+ if (laterNames.size === 0) {
1122
+ return false;
1123
+ }
1124
+ const dependencies = getImmediateDependencyNames(item.node);
1125
+ for (const dependency of dependencies) {
1126
+ if (laterNames.has(dependency)) {
1127
+ return true;
1128
+ }
1129
+ }
1130
+ return false;
954
1131
  });
955
1132
  };
956
1133
  const processExportBlock = (block) => {
package/eslint.config.mjs CHANGED
@@ -30,7 +30,7 @@ export default defineConfig([
30
30
  }
31
31
  },
32
32
  {
33
- files: ["**/*.{ts,js,mjs}"],
33
+ files: ["**/*.{ts,js,mjs,json}"],
34
34
  plugins: {
35
35
  absolute: absolutePlugin
36
36
  },
@@ -92,7 +92,7 @@ export default defineConfig([
92
92
  }
93
93
  },
94
94
  {
95
- files: ["eslint.config.mjs"],
95
+ files: ["eslint.config.mjs", "package.json", "tsconfig.json"],
96
96
  rules: {
97
97
  "@typescript-eslint/no-unused-expressions": "off"
98
98
  }
package/package.json CHANGED
@@ -1,27 +1,9 @@
1
1
  {
2
- "name": "eslint-plugin-absolute",
3
- "version": "0.2.1",
4
- "description": "ESLint plugin for AbsoluteJS",
5
- "repository": {
6
- "type": "git",
7
- "url": "https://github.com/absolutejs/eslint-plugin-absolute.git"
8
- },
9
- "type": "module",
10
- "main": "./dist/index.js",
11
- "license": "CC BY-NC 4.0",
12
2
  "author": "Alex Kahn",
13
- "scripts": {
14
- "test": "bun test tests/",
15
- "build": "rm -rf dist && bun build src/index.ts --outdir dist --splitting --target=bun --external eslint --external @typescript-eslint/utils",
16
- "format": "absolutejs prettier --write",
17
- "release": "bun run format && bun run build && bun publish",
18
- "prune": "ts-prune --error",
19
- "lint": "bun run build && bun run absolutejs eslint",
20
- "typecheck": "bun run tsc --noEmit"
21
- },
3
+ "description": "ESLint plugin for AbsoluteJS",
22
4
  "devDependencies": {
23
- "@types/bun": "1.3.3",
24
5
  "@absolutejs/absolute": "0.16.10",
6
+ "@types/bun": "1.3.3",
25
7
  "@types/react": "19.2.14",
26
8
  "@typescript-eslint/rule-tester": "8.56.0",
27
9
  "@typescript-eslint/utils": "8.56.0",
@@ -30,5 +12,23 @@
30
12
  "ts-prune": "0.10.3",
31
13
  "typescript": "5.9.3",
32
14
  "typescript-eslint": "8.56.0"
33
- }
15
+ },
16
+ "license": "CC BY-NC 4.0",
17
+ "main": "./dist/index.js",
18
+ "name": "eslint-plugin-absolute",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "https://github.com/absolutejs/eslint-plugin-absolute.git"
22
+ },
23
+ "scripts": {
24
+ "build": "rm -rf dist && bun build src/index.ts --outdir dist --splitting --target=bun --external eslint --external @typescript-eslint/utils",
25
+ "format": "absolutejs prettier --write",
26
+ "lint": "bun run build && bun run absolutejs eslint",
27
+ "prune": "ts-prune --error",
28
+ "release": "bun run format && bun run build && bun publish",
29
+ "test": "bun test tests/",
30
+ "typecheck": "bun run tsc --noEmit"
31
+ },
32
+ "type": "module",
33
+ "version": "0.2.2"
34
34
  }
@@ -30,7 +30,51 @@ type ExportItem = {
30
30
  text: string;
31
31
  };
32
32
 
33
- const SORT_BEFORE: -1 = -1;
33
+ const SORT_BEFORE = Number.parseInt("-1", 10);
34
+
35
+ const hasStringTypeProperty = (value: object) => {
36
+ const maybeType = Reflect.get(value, "type");
37
+ return typeof maybeType === "string";
38
+ };
39
+
40
+ const isNodeLike = (value: unknown): value is TSESTree.Node =>
41
+ value !== null &&
42
+ value !== undefined &&
43
+ typeof value === "object" &&
44
+ "type" in value &&
45
+ hasStringTypeProperty(value);
46
+
47
+ const shouldSkipNodeEntry = (key: string, value: unknown) =>
48
+ key === "parent" || value === null || value === undefined;
49
+
50
+ const visitNodeArray = (
51
+ values: unknown[],
52
+ visit: (node: TSESTree.Node | null | undefined) => void
53
+ ) => values.filter(isNodeLike).forEach(visit);
54
+
55
+ const visitNodeEntryValue = (
56
+ value: unknown,
57
+ visit: (node: TSESTree.Node | null | undefined) => void
58
+ ) => {
59
+ if (Array.isArray(value)) {
60
+ visitNodeArray(value, visit);
61
+ return;
62
+ }
63
+
64
+ if (isNodeLike(value)) {
65
+ visit(value);
66
+ }
67
+ };
68
+
69
+ const visitNodeEntries = (
70
+ current: TSESTree.Node,
71
+ visit: (node: TSESTree.Node | null | undefined) => void
72
+ ) =>
73
+ Object.entries(current)
74
+ .filter(([key, value]) => !shouldSkipNodeEntry(key, value))
75
+ .forEach(([, value]) => {
76
+ visitNodeEntryValue(value, visit);
77
+ });
34
78
 
35
79
  const getVariableDeclaratorName = (
36
80
  declaration: TSESTree.VariableDeclaration
@@ -114,6 +158,93 @@ const isFixableExport = (exportNode: TSESTree.ExportNamedDeclaration) => {
114
158
  );
115
159
  };
116
160
 
161
+ const visitImmediateReferences = (
162
+ node: TSESTree.Node | null | undefined,
163
+ onReference: (name: string) => void
164
+ ) => {
165
+ if (!node) {
166
+ return;
167
+ }
168
+
169
+ const visit = (current: TSESTree.Node | null | undefined) => {
170
+ if (!current) {
171
+ return;
172
+ }
173
+
174
+ switch (current.type) {
175
+ case "Identifier":
176
+ onReference(current.name);
177
+ return;
178
+ case "FunctionDeclaration":
179
+ case "FunctionExpression":
180
+ case "ArrowFunctionExpression":
181
+ return;
182
+ case "MemberExpression":
183
+ visit(current.object);
184
+ if (current.computed) {
185
+ visit(current.property);
186
+ }
187
+ return;
188
+ case "Property":
189
+ if (current.computed) {
190
+ visit(current.key);
191
+ }
192
+ visit(current.value);
193
+ return;
194
+ case "PropertyDefinition":
195
+ if (current.computed) {
196
+ visit(current.key);
197
+ }
198
+ if (current.static) {
199
+ visit(current.value);
200
+ }
201
+ return;
202
+ case "MethodDefinition":
203
+ if (current.computed) {
204
+ visit(current.key);
205
+ }
206
+ return;
207
+ case "StaticBlock":
208
+ for (const statement of current.body) {
209
+ visit(statement);
210
+ }
211
+ return;
212
+ }
213
+
214
+ visitNodeEntries(current, visit);
215
+ };
216
+
217
+ visit(node);
218
+ };
219
+
220
+ const getImmediateDependencyNames = (node: TSESTree.ExportNamedDeclaration) => {
221
+ const names = new Set<string>();
222
+ const { declaration } = node;
223
+ const addName = names.add.bind(names);
224
+ const addDeclaratorDependencies = (
225
+ declarator: TSESTree.VariableDeclarator
226
+ ) => visitImmediateReferences(declarator.init, addName);
227
+ const addClassElementDependencies = (
228
+ element: TSESTree.ClassElement | TSESTree.StaticBlock
229
+ ) => visitImmediateReferences(element, addName);
230
+
231
+ if (!declaration) {
232
+ return names;
233
+ }
234
+
235
+ if (declaration.type === "VariableDeclaration") {
236
+ declaration.declarations.forEach(addDeclaratorDependencies);
237
+ return names;
238
+ }
239
+
240
+ if (declaration.type === "ClassDeclaration") {
241
+ visitImmediateReferences(declaration.superClass, addName);
242
+ declaration.body.body.forEach(addClassElementDependencies);
243
+ }
244
+
245
+ return names;
246
+ };
247
+
117
248
  export const sortExports: TSESLint.RuleModule<MessageIds, Options> = {
118
249
  create(context) {
119
250
  const { sourceCode } = context;
@@ -213,23 +344,6 @@ export const sortExports: TSESLint.RuleModule<MessageIds, Options> = {
213
344
  return compareStrings(left.name, right.name);
214
345
  };
215
346
 
216
- /**
217
- * Very lightweight dependency check: look at the text of the node and see
218
- * if it references any of the later export names.
219
- */
220
- const hasForwardDependency = (
221
- node: TSESTree.Node,
222
- laterNames: Set<string>
223
- ) => {
224
- const text = sourceCode.getText(node);
225
- for (const name of laterNames) {
226
- if (text.includes(name)) {
227
- return true;
228
- }
229
- }
230
- return false;
231
- };
232
-
233
347
  const buildItems = (block: TSESTree.ExportNamedDeclaration[]) =>
234
348
  block
235
349
  .map((node) => {
@@ -278,9 +392,17 @@ export const sortExports: TSESLint.RuleModule<MessageIds, Options> = {
278
392
  const exportNames = items.map((item) => item.name);
279
393
  return items.some((item, idx) => {
280
394
  const laterNames = new Set(exportNames.slice(idx + 1));
281
- const nodeToCheck: TSESTree.Node =
282
- item.node.declaration ?? item.node;
283
- return hasForwardDependency(nodeToCheck, laterNames);
395
+ if (laterNames.size === 0) {
396
+ return false;
397
+ }
398
+
399
+ const dependencies = getImmediateDependencyNames(item.node);
400
+ for (const dependency of dependencies) {
401
+ if (laterNames.has(dependency)) {
402
+ return true;
403
+ }
404
+ }
405
+ return false;
284
406
  });
285
407
  };
286
408
 
@@ -36,6 +36,101 @@ type KeyInfo = {
36
36
 
37
37
  const SORT_BEFORE = -1;
38
38
 
39
+ const hasDuplicateNames = (names: Array<string | null>) => {
40
+ const seen = new Set<string>();
41
+ const nonNullNames = names.flatMap((name) => (name === null ? [] : [name]));
42
+
43
+ for (const name of nonNullNames) {
44
+ if (seen.has(name)) {
45
+ return true;
46
+ }
47
+ seen.add(name);
48
+ }
49
+
50
+ return false;
51
+ };
52
+
53
+ const isSafeStaticTemplate = (node: TSESTree.TemplateLiteral) =>
54
+ node.expressions.length === 0;
55
+
56
+ const isSafeArrayElement: (node: TSESTree.Node | null) => boolean = (node) => {
57
+ if (!node || node.type === "SpreadElement") {
58
+ return false;
59
+ }
60
+
61
+ return isSafeToReorderExpression(node);
62
+ };
63
+
64
+ const isSafeObjectProperty: (
65
+ property: TSESTree.ObjectExpression["properties"][number]
66
+ ) => boolean = (property) => {
67
+ if (
68
+ property.type !== "Property" ||
69
+ property.computed ||
70
+ property.kind !== "init"
71
+ ) {
72
+ return false;
73
+ }
74
+
75
+ if (property.key.type !== "Identifier" && property.key.type !== "Literal") {
76
+ return false;
77
+ }
78
+
79
+ if (property.method) {
80
+ return true;
81
+ }
82
+
83
+ return isSafeToReorderExpression(property.value);
84
+ };
85
+
86
+ const isSafeToReorderExpression: (node: TSESTree.Node | null) => boolean = (
87
+ node
88
+ ) => {
89
+ if (!node || node.type === "PrivateIdentifier") {
90
+ return false;
91
+ }
92
+
93
+ switch (node.type) {
94
+ case "Identifier":
95
+ case "Literal":
96
+ case "ThisExpression":
97
+ case "FunctionExpression":
98
+ case "ArrowFunctionExpression":
99
+ case "ClassExpression":
100
+ return true;
101
+ case "TemplateLiteral":
102
+ return isSafeStaticTemplate(node);
103
+ case "UnaryExpression":
104
+ return isSafeToReorderExpression(node.argument);
105
+ case "ArrayExpression":
106
+ return node.elements.every(isSafeArrayElement);
107
+ case "ObjectExpression":
108
+ return node.properties.every(isSafeObjectProperty);
109
+ default:
110
+ return false;
111
+ }
112
+ };
113
+
114
+ const isSafeJSXAttributeValue = (value: TSESTree.JSXAttribute["value"]) => {
115
+ if (value === null) {
116
+ return true;
117
+ }
118
+
119
+ if (value.type === "Literal") {
120
+ return true;
121
+ }
122
+
123
+ if (value.type !== "JSXExpressionContainer") {
124
+ return false;
125
+ }
126
+
127
+ if (value.expression.type === "JSXEmptyExpression") {
128
+ return false;
129
+ }
130
+
131
+ return isSafeToReorderExpression(value.expression);
132
+ };
133
+
39
134
  export const sortKeysFixable: TSESLint.RuleModule<MessageIds, Options> = {
40
135
  create(context) {
41
136
  const { sourceCode } = context;
@@ -367,6 +462,21 @@ export const sortKeysFixable: TSESLint.RuleModule<MessageIds, Options> = {
367
462
  };
368
463
  });
369
464
 
465
+ if (hasDuplicateNames(keys.map((key) => key.keyName))) {
466
+ autoFixable = false;
467
+ }
468
+
469
+ if (
470
+ autoFixable &&
471
+ keys.some(
472
+ (key) =>
473
+ key.node.type === "Property" &&
474
+ !isSafeToReorderExpression(key.node.value)
475
+ )
476
+ ) {
477
+ autoFixable = false;
478
+ }
479
+
370
480
  let fixProvided = false;
371
481
 
372
482
  const createReportWithFix = (curr: KeyInfo, shouldFix: boolean) => {
@@ -538,6 +648,34 @@ export const sortKeysFixable: TSESLint.RuleModule<MessageIds, Options> = {
538
648
  return;
539
649
  }
540
650
 
651
+ if (hasDuplicateNames(names)) {
652
+ context.report({
653
+ messageId: "unsorted",
654
+ node:
655
+ attrs[0]!.type === "JSXAttribute"
656
+ ? attrs[0]!.name
657
+ : attrs[0]!
658
+ });
659
+ return;
660
+ }
661
+
662
+ if (
663
+ attrs.some(
664
+ (attr) =>
665
+ attr.type === "JSXAttribute" &&
666
+ !isSafeJSXAttributeValue(attr.value)
667
+ )
668
+ ) {
669
+ context.report({
670
+ messageId: "unsorted",
671
+ node:
672
+ attrs[0]!.type === "JSXAttribute"
673
+ ? attrs[0]!.name
674
+ : attrs[0]!
675
+ });
676
+ return;
677
+ }
678
+
541
679
  // Be conservative: only fix if there are no JSX comments/braces between attributes.
542
680
  const braceConflict = attrs.find((currAttr, idx) => {
543
681
  if (idx === 0) {
package/tsconfig.json CHANGED
@@ -2,15 +2,15 @@
2
2
  "compilerOptions": {
3
3
  "esModuleInterop": true,
4
4
  "forceConsistentCasingInFileNames": true,
5
+ "incremental": true,
5
6
  "jsx": "react-jsx",
6
7
  "lib": ["DOM", "DOM.Iterable", "ESNext"],
7
8
  "module": "ESNext",
8
9
  "moduleResolution": "bundler",
10
+ "noUncheckedIndexedAccess": true,
9
11
  "skipLibCheck": true,
10
12
  "strict": true,
11
13
  "target": "ESNext",
12
- "noUncheckedIndexedAccess": true,
13
- "incremental": true,
14
14
  "tsBuildInfoFile": ".absolutejs/tsconfig.tsbuildinfo",
15
15
  "types": ["bun-types"]
16
16
  }