ts-codemod-lib 3.3.3 → 3.4.1

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.
Files changed (44) hide show
  1. package/dist/functions/ast-transformers/append-as-const.d.mts +2 -2
  2. package/dist/functions/ast-transformers/append-as-const.d.mts.map +1 -1
  3. package/dist/functions/ast-transformers/append-as-const.mjs +13 -3
  4. package/dist/functions/ast-transformers/append-as-const.mjs.map +1 -1
  5. package/dist/functions/ast-transformers/convert-interface-to-type.d.mts +1 -1
  6. package/dist/functions/ast-transformers/convert-interface-to-type.d.mts.map +1 -1
  7. package/dist/functions/ast-transformers/convert-to-readonly.d.mts +2 -2
  8. package/dist/functions/ast-transformers/convert-to-readonly.d.mts.map +1 -1
  9. package/dist/functions/ast-transformers/convert-to-readonly.mjs +74 -1
  10. package/dist/functions/ast-transformers/convert-to-readonly.mjs.map +1 -1
  11. package/dist/functions/ast-transformers/enable-no-unchecked-indexed-access.d.mts +2 -2
  12. package/dist/functions/ast-transformers/enable-no-unchecked-indexed-access.d.mts.map +1 -1
  13. package/dist/functions/ast-transformers/enable-no-unchecked-indexed-access.mjs +24 -6
  14. package/dist/functions/ast-transformers/enable-no-unchecked-indexed-access.mjs.map +1 -1
  15. package/dist/functions/ast-transformers/readonly-transformer-helpers/readonly-context.d.mts +1 -1
  16. package/dist/functions/ast-transformers/readonly-transformer-helpers/readonly-context.d.mts.map +1 -1
  17. package/dist/functions/ast-transformers/replace-any-with-unknown.d.mts +1 -1
  18. package/dist/functions/ast-transformers/replace-any-with-unknown.d.mts.map +1 -1
  19. package/dist/functions/ast-transformers/replace-record-with-unknown-record.d.mts +1 -1
  20. package/dist/functions/ast-transformers/replace-record-with-unknown-record.d.mts.map +1 -1
  21. package/dist/functions/ast-transformers/transform-source-code.d.mts +1 -1
  22. package/dist/functions/ast-transformers/transform-source-code.d.mts.map +1 -1
  23. package/dist/functions/functions/is-atomic-type-node.d.mts +1 -1
  24. package/dist/functions/functions/is-atomic-type-node.d.mts.map +1 -1
  25. package/dist/functions/functions/is-readonly-node.d.mts +1 -1
  26. package/dist/functions/functions/is-readonly-node.d.mts.map +1 -1
  27. package/dist/functions/functions/unwrap-readonly.d.mts +1 -1
  28. package/dist/functions/functions/unwrap-readonly.d.mts.map +1 -1
  29. package/package.json +16 -16
  30. package/src/functions/ast-transformers/append-as-const.mts +21 -5
  31. package/src/functions/ast-transformers/append-as-const.test.mts +24 -0
  32. package/src/functions/ast-transformers/convert-interface-to-type.mts +1 -1
  33. package/src/functions/ast-transformers/convert-to-readonly.mts +102 -7
  34. package/src/functions/ast-transformers/convert-to-readonly.test.mts +203 -0
  35. package/src/functions/ast-transformers/enable-no-unchecked-indexed-access.mts +30 -8
  36. package/src/functions/ast-transformers/enable-no-unchecked-indexed-access.test.mts +111 -0
  37. package/src/functions/ast-transformers/readonly-transformer-helpers/compare-union-types.mts +1 -1
  38. package/src/functions/ast-transformers/readonly-transformer-helpers/readonly-context.mts +1 -1
  39. package/src/functions/ast-transformers/replace-any-with-unknown.mts +1 -1
  40. package/src/functions/ast-transformers/replace-record-with-unknown-record.mts +1 -1
  41. package/src/functions/ast-transformers/transform-source-code.mts +1 -1
  42. package/src/functions/functions/is-atomic-type-node.mts +1 -1
  43. package/src/functions/functions/is-readonly-node.mts +1 -1
  44. package/src/functions/functions/unwrap-readonly.mts +1 -1
@@ -391,6 +391,96 @@ describe(enableNoUncheckedIndexedAccessTransformer, () => {
391
391
  ])('$name', testFn);
392
392
  });
393
393
 
394
+ describe('positions judged through parentheses and type wrappers', () => {
395
+ test.each([
396
+ {
397
+ name: 'a parenthesized read is still asserted',
398
+ source: 'console.log((xs[0]).toFixed());',
399
+ expected: 'console.log((xs[0]!).toFixed());',
400
+ },
401
+ {
402
+ name: 'parenthesized equality against undefined',
403
+ source: 'console.log((xs[0]) === undefined);',
404
+ expected: 'console.log((xs[0]) === undefined);',
405
+ },
406
+ {
407
+ name: 'parenthesized nullish coalescing',
408
+ source: 'console.log((xs[0]) ?? 0);',
409
+ expected: 'console.log((xs[0]) ?? 0);',
410
+ },
411
+ {
412
+ name: 'parenthesized optional property access',
413
+ source: 'console.log((xs[0])?.toFixed());',
414
+ expected: 'console.log((xs[0])?.toFixed());',
415
+ },
416
+ {
417
+ name: 'parenthesized if condition',
418
+ source: 'if ((xs[0])) { console.log(1); }',
419
+ expected: 'if ((xs[0])) { console.log(1); }',
420
+ },
421
+ {
422
+ name: 'parenthesized typeof operand',
423
+ source: 'console.log(typeof (xs[0]));',
424
+ expected: 'console.log(typeof (xs[0]));',
425
+ },
426
+ {
427
+ name: 'parenthesized negation operand',
428
+ source: 'console.log(!((xs[0])));',
429
+ expected: 'console.log(!((xs[0])));',
430
+ },
431
+ {
432
+ name: 'parenthesized existing non-null assertion',
433
+ source: 'console.log((xs[0])!.toFixed());',
434
+ expected: 'console.log((xs[0])!.toFixed());',
435
+ },
436
+ {
437
+ name: 'parenthesized type assertion',
438
+ source: 'console.log(((xs[0]) as number).toFixed());',
439
+ expected: 'console.log(((xs[0]) as number).toFixed());',
440
+ },
441
+ {
442
+ name: 'satisfies a type without undefined, which needs the assertion',
443
+ source: 'console.log(xs[0] satisfies number);',
444
+ expected: 'console.log(xs[0]! satisfies number);',
445
+ },
446
+ {
447
+ name: 'parenthesized satisfies a type without undefined',
448
+ source: 'console.log((xs[0]) satisfies number);',
449
+ expected: 'console.log((xs[0]!) satisfies number);',
450
+ },
451
+ {
452
+ name: 'satisfies a type with undefined, where the assertion is harmless',
453
+ source: 'console.log(xs[0] satisfies number | undefined);',
454
+ expected: 'console.log(xs[0]! satisfies number | undefined);',
455
+ },
456
+ {
457
+ name: 'parenthesized satisfies a type with undefined',
458
+ source: 'console.log((xs[0]) satisfies number | undefined);',
459
+ expected: 'console.log((xs[0]!) satisfies number | undefined);',
460
+ },
461
+ {
462
+ name: 'parenthesized compound assignment target',
463
+ source: '(mut_ys[0]) += 1;',
464
+ expected: '(mut_ys[0]) += 1;',
465
+ },
466
+ {
467
+ name: 'parenthesized assignment target',
468
+ source: '(mut_ys[0]) = 1;',
469
+ expected: '(mut_ys[0]) = 1;',
470
+ },
471
+ {
472
+ name: 'parenthesized delete target',
473
+ source: "delete (rec['a']);",
474
+ expected: "delete (rec['a']);",
475
+ },
476
+ {
477
+ name: 'parenthesized for-of loop target',
478
+ source: 'for ((mut_ys[0]) of xs) { break; }',
479
+ expected: 'for ((mut_ys[0]) of xs) { break; }',
480
+ },
481
+ ])('$name', testFn);
482
+ });
483
+
394
484
  describe('applyLevel: "avoidWhereUndefinedIsAllowed"', () => {
395
485
  test.each([
396
486
  {
@@ -541,6 +631,27 @@ describe(enableNoUncheckedIndexedAccessTransformer, () => {
541
631
  );
542
632
  });
543
633
 
634
+ test('an access under `satisfies` or in parentheses compiles once transformed', () => {
635
+ const source = dedent`
636
+ declare const xs: readonly number[];
637
+
638
+ export const a = xs[0] satisfies number;
639
+
640
+ export const b = (xs[0]) satisfies number;
641
+
642
+ export const c = (xs[0]).toFixed();
643
+
644
+ export const d = (xs[0]) === undefined ? 0 : (xs[0]) ?? 1;
645
+ `;
646
+
647
+ expect(diagnosticsUnderTheOption(source).length).toBeGreaterThan(0);
648
+
649
+ assert.deepStrictEqual(
650
+ diagnosticsUnderTheOption(transformInProject(source)),
651
+ [],
652
+ );
653
+ });
654
+
544
655
  test('array destructuring is left alone, since `!` has nowhere to go there', () => {
545
656
  const source = dedent`
546
657
  declare const xs: readonly number[];
@@ -1,5 +1,5 @@
1
1
  import * as tsm from 'ts-morph';
2
- import { type DeepReadonly } from 'ts-type-forge';
2
+ import type { DeepReadonly } from 'ts-type-forge';
3
3
  import {
4
4
  isAtomicTypeNode,
5
5
  isReadonlyTupleOrArrayTypeNode,
@@ -1,5 +1,5 @@
1
1
  import { SafeUint, match } from 'ts-data-forge';
2
- import { type SafeUintWithSmallInt, type StrictExtract } from 'ts-type-forge';
2
+ import type { SafeUintWithSmallInt, StrictExtract } from 'ts-type-forge';
3
3
 
4
4
  /**
5
5
  * Controls whether to make a layer mutable during recursive transformation
@@ -4,7 +4,7 @@ import {
4
4
  isSpreadNamedTupleMemberNode,
5
5
  isSpreadParameterNode,
6
6
  } from '../functions/index.mjs';
7
- import { type TsMorphTransformer } from './types.mjs';
7
+ import type { TsMorphTransformer } from './types.mjs';
8
8
 
9
9
  const TRANSFORMER_NAME = 'replace-any-with-unknown';
10
10
 
@@ -2,7 +2,7 @@
2
2
  import { Arr } from 'ts-data-forge';
3
3
  import * as tsm from 'ts-morph';
4
4
  import { hasDisableNextLineComment } from '../functions/index.mjs';
5
- import { type TsMorphTransformer } from './types.mjs';
5
+ import type { TsMorphTransformer } from './types.mjs';
6
6
 
7
7
  const TRANSFORMER_NAME = 'replace-record-with-unknown-record';
8
8
 
@@ -1,6 +1,6 @@
1
1
  import { Arr } from 'ts-data-forge';
2
2
  import * as tsm from 'ts-morph';
3
- import { type TsMorphTransformer } from './types.mjs';
3
+ import type { TsMorphTransformer } from './types.mjs';
4
4
 
5
5
  const fileIgnorePrefixes = [
6
6
  'transformer-ignore',
@@ -1,6 +1,6 @@
1
1
  import { ISet } from 'ts-data-forge';
2
2
  import * as tsm from 'ts-morph';
3
- import { type DeepReadonly } from 'ts-type-forge';
3
+ import type { DeepReadonly } from 'ts-type-forge';
4
4
 
5
5
  // Define the set of SyntaxKinds that represent primitive type keywords
6
6
  const atomicTypeKeywordKinds = ISet.create<tsm.SyntaxKind>([
@@ -1,6 +1,6 @@
1
1
  import { Arr, expectType } from 'ts-data-forge';
2
2
  import * as tsm from 'ts-morph';
3
- import { type DeepReadonly, type StrictOmit } from 'ts-type-forge';
3
+ import type { DeepReadonly, StrictOmit } from 'ts-type-forge';
4
4
  import { isAtomicTypeNode } from './is-atomic-type-node.mjs';
5
5
 
6
6
  export const isShallowReadonlyTypeNode = (node: tsm.Node): boolean =>
@@ -1,4 +1,4 @@
1
- import { type ReadonlyTypeReferenceNode } from './is-readonly-node.mjs';
1
+ import type { ReadonlyTypeReferenceNode } from './is-readonly-node.mjs';
2
2
  import { wrapWithParentheses } from './wrap-with-parentheses.mjs';
3
3
 
4
4
  export const unwrapReadonlyTypeArgText = (