ts-codemod-lib 3.5.1 → 4.0.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.
- package/README.md +7 -3
- package/dist/functions/ast-transformers/append-as-const.d.mts +20 -12
- package/dist/functions/ast-transformers/append-as-const.d.mts.map +1 -1
- package/dist/functions/ast-transformers/append-as-const.mjs +170 -88
- package/dist/functions/ast-transformers/append-as-const.mjs.map +1 -1
- package/dist/functions/ast-transformers/convert-to-readonly.d.mts +25 -6
- package/dist/functions/ast-transformers/convert-to-readonly.d.mts.map +1 -1
- package/dist/functions/ast-transformers/convert-to-readonly.mjs +272 -255
- package/dist/functions/ast-transformers/convert-to-readonly.mjs.map +1 -1
- package/dist/functions/ast-transformers/enable-no-unchecked-indexed-access.d.mts +8 -8
- package/dist/functions/ast-transformers/enable-no-unchecked-indexed-access.mjs +103 -104
- package/dist/functions/ast-transformers/enable-no-unchecked-indexed-access.mjs.map +1 -1
- package/dist/functions/ast-transformers/replace-record-with-unknown-record.d.mts +2 -2
- package/dist/functions/ast-transformers/replace-record-with-unknown-record.mjs +51 -51
- package/dist/functions/ast-transformers/replace-record-with-unknown-record.mjs.map +1 -1
- package/dist/functions/ast-transformers/transform-source-code.d.mts.map +1 -1
- package/dist/functions/ast-transformers/transform-source-code.mjs +69 -69
- package/dist/functions/ast-transformers/transform-source-code.mjs.map +1 -1
- package/dist/functions/constants/index.d.mts +1 -0
- package/dist/functions/constants/index.d.mts.map +1 -1
- package/dist/functions/constants/index.mjs +1 -0
- package/dist/functions/constants/index.mjs.map +1 -1
- package/dist/functions/constants/mutable-prefixes.d.mts +23 -0
- package/dist/functions/constants/mutable-prefixes.d.mts.map +1 -0
- package/dist/functions/constants/mutable-prefixes.mjs +28 -0
- package/dist/functions/constants/mutable-prefixes.mjs.map +1 -0
- package/dist/functions/functions/has-disable-next-line-comment.mjs +23 -23
- package/dist/functions/functions/has-disable-next-line-comment.mjs.map +1 -1
- package/dist/functions/functions/is-readonly-node.d.mts +2 -2
- package/dist/functions/functions/is-readonly-node.d.mts.map +1 -1
- package/dist/functions/functions/is-readonly-node.mjs +13 -13
- package/dist/functions/functions/is-readonly-node.mjs.map +1 -1
- package/dist/functions/functions/wrap-with-parentheses.d.mts +2 -2
- package/dist/functions/functions/wrap-with-parentheses.d.mts.map +1 -1
- package/dist/functions/functions/wrap-with-parentheses.mjs +87 -32
- package/dist/functions/functions/wrap-with-parentheses.mjs.map +1 -1
- package/dist/functions/utils/replace-node-with-text.d.mts +10 -11
- package/dist/functions/utils/replace-node-with-text.d.mts.map +1 -1
- package/dist/functions/utils/replace-node-with-text.mjs +0 -1
- package/dist/functions/utils/replace-node-with-text.mjs.map +1 -1
- package/package.json +6 -6
- package/src/functions/ast-transformers/append-as-const.mts +319 -174
- package/src/functions/ast-transformers/append-as-const.test.mts +118 -7
- package/src/functions/ast-transformers/convert-to-readonly.mts +568 -489
- package/src/functions/ast-transformers/convert-to-readonly.test.mts +381 -74
- package/src/functions/ast-transformers/enable-no-unchecked-indexed-access.mts +178 -179
- package/src/functions/ast-transformers/enable-no-unchecked-indexed-access.test.mts +29 -29
- package/src/functions/ast-transformers/replace-any-with-unknown.test.mts +6 -6
- package/src/functions/ast-transformers/replace-record-with-unknown-record.mts +75 -75
- package/src/functions/ast-transformers/replace-record-with-unknown-record.test.mts +6 -6
- package/src/functions/ast-transformers/transform-source-code.mts +110 -110
- package/src/functions/ast-transformers/transformer-specific-ignore.test.mts +6 -6
- package/src/functions/constants/index.mts +1 -0
- package/src/functions/constants/mutable-prefixes.mts +28 -0
- package/src/functions/functions/has-disable-next-line-comment.mts +35 -35
- package/src/functions/functions/is-readonly-node.mts +25 -25
- package/src/functions/functions/wrap-with-parentheses.mts +138 -52
- package/src/functions/functions/wrap-with-parentheses.test.mts +115 -0
- package/src/functions/utils/replace-node-with-text.mts +10 -11
|
@@ -14,39 +14,6 @@ import {
|
|
|
14
14
|
} from './convert-to-readonly.mjs';
|
|
15
15
|
import { transformSourceCode } from './transform-source-code.mjs';
|
|
16
16
|
|
|
17
|
-
const testFn = async ({
|
|
18
|
-
source,
|
|
19
|
-
expected,
|
|
20
|
-
debug,
|
|
21
|
-
options,
|
|
22
|
-
isTsx = false,
|
|
23
|
-
}: Readonly<{
|
|
24
|
-
source: string;
|
|
25
|
-
expected: string;
|
|
26
|
-
debug?: boolean;
|
|
27
|
-
options?: ReadonlyTransformerOptions;
|
|
28
|
-
isTsx?: boolean;
|
|
29
|
-
}>): Promise<void> => {
|
|
30
|
-
if (debug !== true) {
|
|
31
|
-
// eslint-disable-next-line vitest/no-restricted-vi-methods
|
|
32
|
-
vi.spyOn(console, 'debug').mockImplementation(() => {});
|
|
33
|
-
|
|
34
|
-
// eslint-disable-next-line vitest/no-restricted-vi-methods
|
|
35
|
-
vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
36
|
-
|
|
37
|
-
// eslint-disable-next-line vitest/no-restricted-vi-methods
|
|
38
|
-
vi.spyOn(console, 'trace').mockImplementation(() => {});
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const transformedCodeRaw = await formatter(
|
|
42
|
-
transformSourceCode(source, isTsx, [convertToReadonlyTransformer(options)]),
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
const expectedFormatted = await formatter(expected);
|
|
46
|
-
|
|
47
|
-
expect(transformedCodeRaw).toBe(expectedFormatted);
|
|
48
|
-
};
|
|
49
|
-
|
|
50
17
|
/**
|
|
51
18
|
* Normalizes whitespace in a code string, primarily for comparing AST structure outputs.
|
|
52
19
|
* - Preserves newlines immediately following line comments (`//`).
|
|
@@ -93,6 +60,39 @@ const formatter = async (code: string): Promise<string> => {
|
|
|
93
60
|
});
|
|
94
61
|
};
|
|
95
62
|
|
|
63
|
+
const testFn = async ({
|
|
64
|
+
source,
|
|
65
|
+
expected,
|
|
66
|
+
debug,
|
|
67
|
+
options,
|
|
68
|
+
isTsx = false,
|
|
69
|
+
}: Readonly<{
|
|
70
|
+
source: string;
|
|
71
|
+
expected: string;
|
|
72
|
+
debug?: boolean;
|
|
73
|
+
options?: ReadonlyTransformerOptions;
|
|
74
|
+
isTsx?: boolean;
|
|
75
|
+
}>): Promise<void> => {
|
|
76
|
+
if (debug !== true) {
|
|
77
|
+
// eslint-disable-next-line vitest/no-restricted-vi-methods
|
|
78
|
+
vi.spyOn(console, 'debug').mockImplementation(() => {});
|
|
79
|
+
|
|
80
|
+
// eslint-disable-next-line vitest/no-restricted-vi-methods
|
|
81
|
+
vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
82
|
+
|
|
83
|
+
// eslint-disable-next-line vitest/no-restricted-vi-methods
|
|
84
|
+
vi.spyOn(console, 'trace').mockImplementation(() => {});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const transformedCodeRaw = await formatter(
|
|
88
|
+
transformSourceCode(source, isTsx, [convertToReadonlyTransformer(options)]),
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
const expectedFormatted = await formatter(expected);
|
|
92
|
+
|
|
93
|
+
expect(transformedCodeRaw).toBe(expectedFormatted);
|
|
94
|
+
};
|
|
95
|
+
|
|
96
96
|
describe(convertToReadonlyTransformer, () => {
|
|
97
97
|
describe('TypeReferences', () => {
|
|
98
98
|
describe('Sets', () => {
|
|
@@ -788,6 +788,33 @@ describe(convertToReadonlyTransformer, () => {
|
|
|
788
788
|
function foo(a: readonly number[], b: Promise<readonly number[]>) {}
|
|
789
789
|
`,
|
|
790
790
|
},
|
|
791
|
+
{
|
|
792
|
+
name: 'Array<T> whose element type has a parenthesis inside a string literal type',
|
|
793
|
+
source: dedent`
|
|
794
|
+
type T = Array<(A | '(') | (B)>;
|
|
795
|
+
`,
|
|
796
|
+
expected: dedent`
|
|
797
|
+
type T = readonly ((A | '(') | (B))[];
|
|
798
|
+
`,
|
|
799
|
+
},
|
|
800
|
+
{
|
|
801
|
+
name: 'Array<T> whose element type has a parenthesis inside a comment',
|
|
802
|
+
source: dedent`
|
|
803
|
+
type T = Array<(A | /* ( */ C) | (B)>;
|
|
804
|
+
`,
|
|
805
|
+
expected: dedent`
|
|
806
|
+
type T = readonly ((A | /* ( */ C) | (B))[];
|
|
807
|
+
`,
|
|
808
|
+
},
|
|
809
|
+
{
|
|
810
|
+
name: 'Array<T> whose element type has a parenthesis inside a template literal type',
|
|
811
|
+
source: dedent`
|
|
812
|
+
type T = Array<(\`(\${A}\` | C) | (B)>;
|
|
813
|
+
`,
|
|
814
|
+
expected: dedent`
|
|
815
|
+
type T = readonly ((\`(\${A}\` | C) | (B))[];
|
|
816
|
+
`,
|
|
817
|
+
},
|
|
791
818
|
{
|
|
792
819
|
name: 'Mutable array types in function args (generic)',
|
|
793
820
|
source: dedent`
|
|
@@ -1980,6 +2007,7 @@ describe(convertToReadonlyTransformer, () => {
|
|
|
1980
2007
|
}
|
|
1981
2008
|
}
|
|
1982
2009
|
`,
|
|
2010
|
+
options: { mutablePropertyPrefixes: ['_mut_'] },
|
|
1983
2011
|
},
|
|
1984
2012
|
{
|
|
1985
2013
|
name: 'Method with "draft" prefix',
|
|
@@ -1997,6 +2025,7 @@ describe(convertToReadonlyTransformer, () => {
|
|
|
1997
2025
|
}
|
|
1998
2026
|
}
|
|
1999
2027
|
`,
|
|
2028
|
+
options: { mutablePropertyPrefixes: ['draft'] },
|
|
2000
2029
|
},
|
|
2001
2030
|
{
|
|
2002
2031
|
name: 'Method without mut_ prefix should be transformed',
|
|
@@ -3977,15 +4006,20 @@ describe(convertToReadonlyTransformer, () => {
|
|
|
3977
4006
|
type T = { draftItems: number[]; readonly b: readonly string[] };
|
|
3978
4007
|
type U = { mutable_items: number[]; readonly b: readonly string[] };
|
|
3979
4008
|
`,
|
|
3980
|
-
options: {
|
|
4009
|
+
options: {
|
|
4010
|
+
mutableVariablePrefixes: ['draft', 'mutable_'],
|
|
4011
|
+
mutablePropertyPrefixes: ['draft', 'mutable_'],
|
|
4012
|
+
},
|
|
3981
4013
|
},
|
|
3982
4014
|
{
|
|
3983
|
-
name: '
|
|
4015
|
+
name: '"mut_" alone is the default: it covers "#mut_" and no longer "_mut_"',
|
|
3984
4016
|
source: dedent`
|
|
3985
4017
|
type T = { _mut_items: number[]; b: string[] };
|
|
4018
|
+
class C { #mut_items: number[] = []; c: string[] = []; }
|
|
3986
4019
|
`,
|
|
3987
4020
|
expected: dedent`
|
|
3988
|
-
type T = { _mut_items: number[];
|
|
4021
|
+
type T = Readonly<{ _mut_items: readonly number[]; b: readonly string[] }>;
|
|
4022
|
+
class C { #mut_items: number[] = []; readonly c: readonly string[] = []; }
|
|
3989
4023
|
`,
|
|
3990
4024
|
},
|
|
3991
4025
|
{
|
|
@@ -4291,7 +4325,7 @@ describe(convertToReadonlyTransformer, () => {
|
|
|
4291
4325
|
expected: dedent`
|
|
4292
4326
|
type T = Readonly<{ mut_a: readonly number[]; b: readonly string[] }>;
|
|
4293
4327
|
`,
|
|
4294
|
-
options: {
|
|
4328
|
+
options: { mutableVariablePrefixes: [], mutablePropertyPrefixes: [] },
|
|
4295
4329
|
},
|
|
4296
4330
|
])('$name', testFn);
|
|
4297
4331
|
|
|
@@ -4849,7 +4883,7 @@ describe(convertToReadonlyTransformer, () => {
|
|
|
4849
4883
|
])('$name', testFn);
|
|
4850
4884
|
});
|
|
4851
4885
|
|
|
4852
|
-
describe('
|
|
4886
|
+
describe('mutableVariablePrefixes and mutablePropertyPrefixes options', () => {
|
|
4853
4887
|
test.each([
|
|
4854
4888
|
{
|
|
4855
4889
|
name: 'Variable declarations',
|
|
@@ -4872,10 +4906,10 @@ describe(convertToReadonlyTransformer, () => {
|
|
|
4872
4906
|
{
|
|
4873
4907
|
name: 'Type aliases',
|
|
4874
4908
|
source: dedent`
|
|
4875
|
-
type
|
|
4909
|
+
type MutableFoo = number[]
|
|
4876
4910
|
`,
|
|
4877
4911
|
expected: dedent`
|
|
4878
|
-
type
|
|
4912
|
+
type MutableFoo = number[]
|
|
4879
4913
|
`,
|
|
4880
4914
|
},
|
|
4881
4915
|
{
|
|
@@ -4889,7 +4923,10 @@ describe(convertToReadonlyTransformer, () => {
|
|
|
4889
4923
|
readonly normalValue: readonly string[];
|
|
4890
4924
|
};
|
|
4891
4925
|
`,
|
|
4892
|
-
options: {
|
|
4926
|
+
options: {
|
|
4927
|
+
mutableVariablePrefixes: ['mut_'],
|
|
4928
|
+
mutablePropertyPrefixes: ['mut_'],
|
|
4929
|
+
},
|
|
4893
4930
|
},
|
|
4894
4931
|
{
|
|
4895
4932
|
name: 'Multiple ignore prefixes',
|
|
@@ -4903,7 +4940,10 @@ describe(convertToReadonlyTransformer, () => {
|
|
|
4903
4940
|
readonly normalValue: readonly boolean[];
|
|
4904
4941
|
};
|
|
4905
4942
|
`,
|
|
4906
|
-
options: {
|
|
4943
|
+
options: {
|
|
4944
|
+
mutableVariablePrefixes: ['mut_', 'mutable_'],
|
|
4945
|
+
mutablePropertyPrefixes: ['mut_', 'mutable_'],
|
|
4946
|
+
},
|
|
4907
4947
|
},
|
|
4908
4948
|
{
|
|
4909
4949
|
name: 'Ignore prefix in nested properties',
|
|
@@ -4923,7 +4963,10 @@ describe(convertToReadonlyTransformer, () => {
|
|
|
4923
4963
|
};
|
|
4924
4964
|
}>;
|
|
4925
4965
|
`,
|
|
4926
|
-
options: {
|
|
4966
|
+
options: {
|
|
4967
|
+
mutableVariablePrefixes: ['mut_'],
|
|
4968
|
+
mutablePropertyPrefixes: ['mut_'],
|
|
4969
|
+
},
|
|
4927
4970
|
},
|
|
4928
4971
|
{
|
|
4929
4972
|
name: 'Ignore prefix in interface',
|
|
@@ -4939,7 +4982,10 @@ describe(convertToReadonlyTransformer, () => {
|
|
|
4939
4982
|
readonly roles: readonly string[];
|
|
4940
4983
|
}
|
|
4941
4984
|
`,
|
|
4942
|
-
options: {
|
|
4985
|
+
options: {
|
|
4986
|
+
mutableVariablePrefixes: ['mut_'],
|
|
4987
|
+
mutablePropertyPrefixes: ['mut_'],
|
|
4988
|
+
},
|
|
4943
4989
|
},
|
|
4944
4990
|
{
|
|
4945
4991
|
name: 'Ignore prefixes for various name node types in interface',
|
|
@@ -4961,7 +5007,10 @@ describe(convertToReadonlyTransformer, () => {
|
|
|
4961
5007
|
readonly ['mu' + 't_d']: readonly string[]; // ComputedPropertyName
|
|
4962
5008
|
}
|
|
4963
5009
|
`,
|
|
4964
|
-
options: {
|
|
5010
|
+
options: {
|
|
5011
|
+
mutableVariablePrefixes: ['mut_'],
|
|
5012
|
+
mutablePropertyPrefixes: ['mut_'],
|
|
5013
|
+
},
|
|
4965
5014
|
},
|
|
4966
5015
|
{
|
|
4967
5016
|
name: 'Ignore prefix with index signature',
|
|
@@ -4979,7 +5028,10 @@ describe(convertToReadonlyTransformer, () => {
|
|
|
4979
5028
|
};
|
|
4980
5029
|
};
|
|
4981
5030
|
`,
|
|
4982
|
-
options: {
|
|
5031
|
+
options: {
|
|
5032
|
+
mutableVariablePrefixes: ['mut_'],
|
|
5033
|
+
mutablePropertyPrefixes: ['mut_'],
|
|
5034
|
+
},
|
|
4983
5035
|
},
|
|
4984
5036
|
{
|
|
4985
5037
|
name: 'Index signature in ignored property',
|
|
@@ -4997,21 +5049,27 @@ describe(convertToReadonlyTransformer, () => {
|
|
|
4997
5049
|
};
|
|
4998
5050
|
}
|
|
4999
5051
|
`,
|
|
5000
|
-
options: {
|
|
5052
|
+
options: {
|
|
5053
|
+
mutableVariablePrefixes: ['mut_'],
|
|
5054
|
+
mutablePropertyPrefixes: ['mut_'],
|
|
5055
|
+
},
|
|
5001
5056
|
},
|
|
5002
5057
|
{
|
|
5003
5058
|
name: 'Type alias with ignored prefix',
|
|
5004
5059
|
source: dedent`
|
|
5005
|
-
type
|
|
5060
|
+
type MutableConfig = {
|
|
5006
5061
|
items: string[];
|
|
5007
5062
|
};
|
|
5008
5063
|
`,
|
|
5009
5064
|
expected: dedent`
|
|
5010
|
-
type
|
|
5065
|
+
type MutableConfig = {
|
|
5011
5066
|
items: string[];
|
|
5012
5067
|
};
|
|
5013
5068
|
`,
|
|
5014
|
-
options: {
|
|
5069
|
+
options: {
|
|
5070
|
+
mutableVariablePrefixes: ['mut_'],
|
|
5071
|
+
mutablePropertyPrefixes: ['mut_'],
|
|
5072
|
+
},
|
|
5015
5073
|
},
|
|
5016
5074
|
{
|
|
5017
5075
|
name: 'Function with ignored prefix',
|
|
@@ -5021,21 +5079,27 @@ describe(convertToReadonlyTransformer, () => {
|
|
|
5021
5079
|
expected: dedent`
|
|
5022
5080
|
function mut_process(data: string[]): number[] { return []; }
|
|
5023
5081
|
`,
|
|
5024
|
-
options: {
|
|
5082
|
+
options: {
|
|
5083
|
+
mutableVariablePrefixes: ['mut_'],
|
|
5084
|
+
mutablePropertyPrefixes: ['mut_'],
|
|
5085
|
+
},
|
|
5025
5086
|
},
|
|
5026
5087
|
{
|
|
5027
5088
|
name: 'Class with ignored prefix',
|
|
5028
5089
|
source: dedent`
|
|
5029
|
-
class
|
|
5090
|
+
class MutableStore {
|
|
5030
5091
|
items: string[] = [];
|
|
5031
5092
|
}
|
|
5032
5093
|
`,
|
|
5033
5094
|
expected: dedent`
|
|
5034
|
-
class
|
|
5095
|
+
class MutableStore {
|
|
5035
5096
|
items: string[] = [];
|
|
5036
5097
|
}
|
|
5037
5098
|
`,
|
|
5038
|
-
options: {
|
|
5099
|
+
options: {
|
|
5100
|
+
mutableVariablePrefixes: ['mut_'],
|
|
5101
|
+
mutablePropertyPrefixes: ['mut_'],
|
|
5102
|
+
},
|
|
5039
5103
|
},
|
|
5040
5104
|
{
|
|
5041
5105
|
name: 'Variable declaration with ignored prefix',
|
|
@@ -5045,37 +5109,46 @@ describe(convertToReadonlyTransformer, () => {
|
|
|
5045
5109
|
expected: dedent`
|
|
5046
5110
|
const mut_items: string[] = []
|
|
5047
5111
|
`,
|
|
5048
|
-
options: {
|
|
5112
|
+
options: {
|
|
5113
|
+
mutableVariablePrefixes: ['mut_'],
|
|
5114
|
+
mutablePropertyPrefixes: ['mut_'],
|
|
5115
|
+
},
|
|
5049
5116
|
},
|
|
5050
5117
|
{
|
|
5051
5118
|
name: 'Generic type with ignored prefix',
|
|
5052
5119
|
source: dedent`
|
|
5053
|
-
type
|
|
5120
|
+
type MutableList<T> = {
|
|
5054
5121
|
items: T[]
|
|
5055
5122
|
}
|
|
5056
5123
|
`,
|
|
5057
5124
|
expected: dedent`
|
|
5058
|
-
type
|
|
5125
|
+
type MutableList<T> = {
|
|
5059
5126
|
items: T[];
|
|
5060
5127
|
};
|
|
5061
5128
|
`,
|
|
5062
|
-
options: {
|
|
5129
|
+
options: {
|
|
5130
|
+
mutableVariablePrefixes: ['mut_'],
|
|
5131
|
+
mutablePropertyPrefixes: ['mut_'],
|
|
5132
|
+
},
|
|
5063
5133
|
},
|
|
5064
5134
|
{
|
|
5065
5135
|
name: 'Union type with ignored prefix members',
|
|
5066
5136
|
source: dedent`
|
|
5067
|
-
type Result =
|
|
5068
|
-
type
|
|
5137
|
+
type Result = MutableSuccess | Error;
|
|
5138
|
+
type MutableSuccess = {
|
|
5069
5139
|
data: string[]
|
|
5070
5140
|
};
|
|
5071
5141
|
`,
|
|
5072
5142
|
expected: dedent`
|
|
5073
|
-
type Result =
|
|
5074
|
-
type
|
|
5143
|
+
type Result = MutableSuccess | Error;
|
|
5144
|
+
type MutableSuccess = {
|
|
5075
5145
|
data: string[];
|
|
5076
5146
|
};
|
|
5077
5147
|
`,
|
|
5078
|
-
options: {
|
|
5148
|
+
options: {
|
|
5149
|
+
mutableVariablePrefixes: ['mut_'],
|
|
5150
|
+
mutablePropertyPrefixes: ['mut_'],
|
|
5151
|
+
},
|
|
5079
5152
|
},
|
|
5080
5153
|
{
|
|
5081
5154
|
name: 'Property with ignored prefix in class',
|
|
@@ -5091,7 +5164,10 @@ describe(convertToReadonlyTransformer, () => {
|
|
|
5091
5164
|
readonly items: readonly number[] = [];
|
|
5092
5165
|
}
|
|
5093
5166
|
`,
|
|
5094
|
-
options: {
|
|
5167
|
+
options: {
|
|
5168
|
+
mutableVariablePrefixes: ['mut_'],
|
|
5169
|
+
mutablePropertyPrefixes: ['mut_'],
|
|
5170
|
+
},
|
|
5095
5171
|
},
|
|
5096
5172
|
{
|
|
5097
5173
|
name: 'Method parameter with ignored prefix',
|
|
@@ -5105,7 +5181,10 @@ describe(convertToReadonlyTransformer, () => {
|
|
|
5105
5181
|
process(mut_data: string[], data: readonly number[]) {}
|
|
5106
5182
|
}
|
|
5107
5183
|
`,
|
|
5108
|
-
options: {
|
|
5184
|
+
options: {
|
|
5185
|
+
mutableVariablePrefixes: ['mut_'],
|
|
5186
|
+
mutablePropertyPrefixes: ['mut_'],
|
|
5187
|
+
},
|
|
5109
5188
|
},
|
|
5110
5189
|
{
|
|
5111
5190
|
name: 'Function expression with ignored prefix',
|
|
@@ -5115,7 +5194,10 @@ describe(convertToReadonlyTransformer, () => {
|
|
|
5115
5194
|
expected: dedent`
|
|
5116
5195
|
const fn = function mut_process(data: string[]): number[] { return []; }
|
|
5117
5196
|
`,
|
|
5118
|
-
options: {
|
|
5197
|
+
options: {
|
|
5198
|
+
mutableVariablePrefixes: ['mut_'],
|
|
5199
|
+
mutablePropertyPrefixes: ['mut_'],
|
|
5200
|
+
},
|
|
5119
5201
|
},
|
|
5120
5202
|
{
|
|
5121
5203
|
name: 'Array binding pattern in variable declaration (not implemented)',
|
|
@@ -5125,7 +5207,10 @@ describe(convertToReadonlyTransformer, () => {
|
|
|
5125
5207
|
expected: dedent`
|
|
5126
5208
|
const [mut_first, mut_second]: readonly [readonly string[], readonly number[]] = [[], []];
|
|
5127
5209
|
`,
|
|
5128
|
-
options: {
|
|
5210
|
+
options: {
|
|
5211
|
+
mutableVariablePrefixes: ['mut_'],
|
|
5212
|
+
mutablePropertyPrefixes: ['mut_'],
|
|
5213
|
+
},
|
|
5129
5214
|
},
|
|
5130
5215
|
{
|
|
5131
5216
|
// The binding pattern itself is not looked at (see the TODO in
|
|
@@ -5137,7 +5222,10 @@ describe(convertToReadonlyTransformer, () => {
|
|
|
5137
5222
|
expected: dedent`
|
|
5138
5223
|
const { mut_arr, mut_obj }: { mut_arr: string[], mut_obj: number[] } = { mut_arr: [], mut_obj: [] };
|
|
5139
5224
|
`,
|
|
5140
|
-
options: {
|
|
5225
|
+
options: {
|
|
5226
|
+
mutableVariablePrefixes: ['mut_'],
|
|
5227
|
+
mutablePropertyPrefixes: ['mut_'],
|
|
5228
|
+
},
|
|
5141
5229
|
},
|
|
5142
5230
|
{
|
|
5143
5231
|
name: 'Parameter with ignored prefix in class constructor',
|
|
@@ -5151,7 +5239,10 @@ describe(convertToReadonlyTransformer, () => {
|
|
|
5151
5239
|
constructor(mut_config: string[]) {}
|
|
5152
5240
|
}
|
|
5153
5241
|
`,
|
|
5154
|
-
options: {
|
|
5242
|
+
options: {
|
|
5243
|
+
mutableVariablePrefixes: ['mut_'],
|
|
5244
|
+
mutablePropertyPrefixes: ['mut_'],
|
|
5245
|
+
},
|
|
5155
5246
|
},
|
|
5156
5247
|
{
|
|
5157
5248
|
name: 'Parameter with ignored prefix in type literal method',
|
|
@@ -5165,7 +5256,10 @@ describe(convertToReadonlyTransformer, () => {
|
|
|
5165
5256
|
process(mut_data: string[]): void;
|
|
5166
5257
|
}>;
|
|
5167
5258
|
`,
|
|
5168
|
-
options: {
|
|
5259
|
+
options: {
|
|
5260
|
+
mutableVariablePrefixes: ['mut_'],
|
|
5261
|
+
mutablePropertyPrefixes: ['mut_'],
|
|
5262
|
+
},
|
|
5169
5263
|
},
|
|
5170
5264
|
{
|
|
5171
5265
|
name: 'Multiple parameters with ignored prefix',
|
|
@@ -5179,7 +5273,10 @@ describe(convertToReadonlyTransformer, () => {
|
|
|
5179
5273
|
update(mut_id: string, mut_data: object[], data: readonly string[]): void;
|
|
5180
5274
|
}
|
|
5181
5275
|
`,
|
|
5182
|
-
options: {
|
|
5276
|
+
options: {
|
|
5277
|
+
mutableVariablePrefixes: ['mut_'],
|
|
5278
|
+
mutablePropertyPrefixes: ['mut_'],
|
|
5279
|
+
},
|
|
5183
5280
|
},
|
|
5184
5281
|
{
|
|
5185
5282
|
name: 'Arrow function with ignored prefix parameters',
|
|
@@ -5189,18 +5286,228 @@ describe(convertToReadonlyTransformer, () => {
|
|
|
5189
5286
|
expected: dedent`
|
|
5190
5287
|
const handler = (mut_event: Event[], event: readonly CustomEvent[]) => {};
|
|
5191
5288
|
`,
|
|
5192
|
-
options: {
|
|
5289
|
+
options: {
|
|
5290
|
+
mutableVariablePrefixes: ['mut_'],
|
|
5291
|
+
mutablePropertyPrefixes: ['mut_'],
|
|
5292
|
+
},
|
|
5193
5293
|
},
|
|
5194
5294
|
{
|
|
5195
|
-
name: '
|
|
5295
|
+
name: '"draft" is not a default prefix',
|
|
5196
5296
|
source: dedent`
|
|
5197
5297
|
const handler = (draft: Event[], event: CustomEvent[]) => {};
|
|
5298
|
+
type T = { draft: boolean; items: string[] };
|
|
5299
|
+
`,
|
|
5300
|
+
expected: dedent`
|
|
5301
|
+
const handler = (draft: readonly Event[], event: readonly CustomEvent[]) => {};
|
|
5302
|
+
type T = Readonly<{ draft: boolean; items: readonly string[] }>;
|
|
5303
|
+
`,
|
|
5304
|
+
},
|
|
5305
|
+
{
|
|
5306
|
+
name: '"Mutable" and "mut_" are the default type prefixes',
|
|
5307
|
+
source: dedent`
|
|
5308
|
+
type MutableFoo = { a: string[] };
|
|
5309
|
+
interface MutableBar { a: string[] }
|
|
5310
|
+
class MutableBaz { a: string[] = []; }
|
|
5311
|
+
const Q = class MutableQ { a: string[] = []; };
|
|
5312
|
+
type mut_Qux = { a: string[] };
|
|
5313
|
+
type Foo = { a: MutableFoo[] };
|
|
5314
|
+
`,
|
|
5315
|
+
expected: dedent`
|
|
5316
|
+
type MutableFoo = { a: string[] };
|
|
5317
|
+
interface MutableBar { a: string[] }
|
|
5318
|
+
class MutableBaz { a: string[] = []; }
|
|
5319
|
+
const Q = class MutableQ { a: string[] = []; };
|
|
5320
|
+
type mut_Qux = { a: string[] };
|
|
5321
|
+
type Foo = Readonly<{ a: readonly MutableFoo[] }>;
|
|
5322
|
+
`,
|
|
5323
|
+
},
|
|
5324
|
+
{
|
|
5325
|
+
name: 'Variable and property prefixes are separate',
|
|
5326
|
+
source: dedent`
|
|
5327
|
+
const handler = (draft: Event[]) => {};
|
|
5328
|
+
type T = { draft: boolean; items: string[] };
|
|
5329
|
+
`,
|
|
5330
|
+
expected: dedent`
|
|
5331
|
+
const handler = (draft: Event[]) => {};
|
|
5332
|
+
type T = Readonly<{ draft: boolean; items: readonly string[] }>;
|
|
5333
|
+
`,
|
|
5334
|
+
options: { mutableVariablePrefixes: ['draft'] },
|
|
5335
|
+
},
|
|
5336
|
+
{
|
|
5337
|
+
name: 'Each kind of name is matched against its own list: variables',
|
|
5338
|
+
source: dedent`
|
|
5339
|
+
type mut_T = { a: string[] };
|
|
5340
|
+
interface mut_I { a: string[] }
|
|
5341
|
+
class mut_C { a: string[] = []; }
|
|
5342
|
+
function mut_f(a: string[]): void {}
|
|
5343
|
+
const mut_x: string[] = [];
|
|
5344
|
+
type U = [mut_a: string[], b: string[]];
|
|
5345
|
+
class D { #mut_p: string[] = []; 'mut_q': string[] = []; }
|
|
5346
|
+
type V = { mut_r: string[]; s: string[] };
|
|
5347
|
+
interface J { mut_a: string[]; f(mut_p: string[]): void }
|
|
5348
|
+
type W = { mut_m(): string[]; b: string[] };
|
|
5349
|
+
class E { mut_m(x: string[]): string[] { return []; } get mut_g(): string[] { return []; } }
|
|
5350
|
+
`,
|
|
5351
|
+
expected: dedent`
|
|
5352
|
+
type mut_T = Readonly<{ a: readonly string[] }>;
|
|
5353
|
+
interface mut_I { readonly a: readonly string[] }
|
|
5354
|
+
class mut_C { readonly a: readonly string[] = []; }
|
|
5355
|
+
function mut_f(a: string[]): void {}
|
|
5356
|
+
const mut_x: string[] = [];
|
|
5357
|
+
type U = readonly [mut_a: readonly string[], b: readonly string[]];
|
|
5358
|
+
class D { readonly #mut_p: readonly string[] = []; readonly 'mut_q': readonly string[] = []; }
|
|
5359
|
+
type V = Readonly<{ mut_r: readonly string[]; s: readonly string[] }>;
|
|
5360
|
+
interface J { readonly mut_a: readonly string[]; f(mut_p: string[]): void }
|
|
5361
|
+
type W = Readonly<{ mut_m(): readonly string[]; b: readonly string[] }>;
|
|
5362
|
+
class E { mut_m(x: readonly string[]): readonly string[] { return []; } get mut_g(): readonly string[] { return []; } }
|
|
5363
|
+
`,
|
|
5364
|
+
options: {
|
|
5365
|
+
mutableVariablePrefixes: ['mut_'],
|
|
5366
|
+
mutableTypePrefixes: [],
|
|
5367
|
+
mutablePropertyPrefixes: [],
|
|
5368
|
+
},
|
|
5369
|
+
},
|
|
5370
|
+
{
|
|
5371
|
+
name: 'Each kind of name is matched against its own list: types',
|
|
5372
|
+
source: dedent`
|
|
5373
|
+
type mut_T = { a: string[] };
|
|
5374
|
+
interface mut_I { a: string[] }
|
|
5375
|
+
class mut_C { a: string[] = []; }
|
|
5376
|
+
function mut_f(a: string[]): void {}
|
|
5377
|
+
const mut_x: string[] = [];
|
|
5378
|
+
type U = [mut_a: string[], b: string[]];
|
|
5379
|
+
class D { #mut_p: string[] = []; 'mut_q': string[] = []; }
|
|
5380
|
+
type V = { mut_r: string[]; s: string[] };
|
|
5381
|
+
interface J { mut_a: string[]; f(mut_p: string[]): void }
|
|
5382
|
+
type W = { mut_m(): string[]; b: string[] };
|
|
5383
|
+
class E { mut_m(x: string[]): string[] { return []; } get mut_g(): string[] { return []; } }
|
|
5384
|
+
`,
|
|
5385
|
+
expected: dedent`
|
|
5386
|
+
type mut_T = { a: string[] };
|
|
5387
|
+
interface mut_I { a: string[] }
|
|
5388
|
+
class mut_C { a: string[] = []; }
|
|
5389
|
+
function mut_f(a: readonly string[]): void {}
|
|
5390
|
+
const mut_x: readonly string[] = [];
|
|
5391
|
+
type U = readonly [mut_a: readonly string[], b: readonly string[]];
|
|
5392
|
+
class D { readonly #mut_p: readonly string[] = []; readonly 'mut_q': readonly string[] = []; }
|
|
5393
|
+
type V = Readonly<{ mut_r: readonly string[]; s: readonly string[] }>;
|
|
5394
|
+
interface J { readonly mut_a: readonly string[]; f(mut_p: readonly string[]): void }
|
|
5395
|
+
type W = Readonly<{ mut_m(): readonly string[]; b: readonly string[] }>;
|
|
5396
|
+
class E { mut_m(x: readonly string[]): readonly string[] { return []; } get mut_g(): readonly string[] { return []; } }
|
|
5397
|
+
`,
|
|
5398
|
+
options: {
|
|
5399
|
+
mutableVariablePrefixes: [],
|
|
5400
|
+
mutableTypePrefixes: ['mut_'],
|
|
5401
|
+
mutablePropertyPrefixes: [],
|
|
5402
|
+
},
|
|
5403
|
+
},
|
|
5404
|
+
{
|
|
5405
|
+
name: 'Each kind of name is matched against its own list: properties',
|
|
5406
|
+
source: dedent`
|
|
5407
|
+
type mut_T = { a: string[] };
|
|
5408
|
+
interface mut_I { a: string[] }
|
|
5409
|
+
class mut_C { a: string[] = []; }
|
|
5410
|
+
function mut_f(a: string[]): void {}
|
|
5411
|
+
const mut_x: string[] = [];
|
|
5412
|
+
type U = [mut_a: string[], b: string[]];
|
|
5413
|
+
class D { #mut_p: string[] = []; 'mut_q': string[] = []; }
|
|
5414
|
+
type V = { mut_r: string[]; s: string[] };
|
|
5415
|
+
interface J { mut_a: string[]; f(mut_p: string[]): void }
|
|
5416
|
+
type W = { mut_m(): string[]; b: string[] };
|
|
5417
|
+
class E { mut_m(x: string[]): string[] { return []; } get mut_g(): string[] { return []; } }
|
|
5418
|
+
`,
|
|
5419
|
+
expected: dedent`
|
|
5420
|
+
type mut_T = Readonly<{ a: readonly string[] }>;
|
|
5421
|
+
interface mut_I { readonly a: readonly string[] }
|
|
5422
|
+
class mut_C { readonly a: readonly string[] = []; }
|
|
5423
|
+
function mut_f(a: readonly string[]): void {}
|
|
5424
|
+
const mut_x: readonly string[] = [];
|
|
5425
|
+
type U = readonly [mut_a: string[], b: readonly string[]];
|
|
5426
|
+
class D { #mut_p: string[] = []; 'mut_q': string[] = []; }
|
|
5427
|
+
type V = { mut_r: string[]; readonly s: readonly string[] };
|
|
5428
|
+
interface J { mut_a: string[]; f(mut_p: readonly string[]): void }
|
|
5429
|
+
type W = { mut_m(): string[]; readonly b: readonly string[] };
|
|
5430
|
+
class E { mut_m(x: string[]): string[] { return []; } get mut_g(): string[] { return []; } }
|
|
5431
|
+
`,
|
|
5432
|
+
options: {
|
|
5433
|
+
mutableVariablePrefixes: [],
|
|
5434
|
+
mutableTypePrefixes: [],
|
|
5435
|
+
mutablePropertyPrefixes: ['mut_'],
|
|
5436
|
+
},
|
|
5437
|
+
},
|
|
5438
|
+
{
|
|
5439
|
+
name: 'A property prefix with a "#" covers private names only',
|
|
5440
|
+
source: dedent`
|
|
5441
|
+
class C { #mut_a: string[] = []; mut_b: string[] = []; }
|
|
5442
|
+
`,
|
|
5443
|
+
expected: dedent`
|
|
5444
|
+
class C { #mut_a: string[] = []; readonly mut_b: readonly string[] = []; }
|
|
5445
|
+
`,
|
|
5446
|
+
options: { mutablePropertyPrefixes: ['#mut_'] },
|
|
5447
|
+
},
|
|
5448
|
+
{
|
|
5449
|
+
name: 'A property prefix does not apply to variables',
|
|
5450
|
+
source: dedent`
|
|
5451
|
+
const handler = (draft: Event[]) => {};
|
|
5452
|
+
type T = { draft: boolean; items: string[] };
|
|
5453
|
+
`,
|
|
5454
|
+
expected: dedent`
|
|
5455
|
+
const handler = (draft: readonly Event[]) => {};
|
|
5456
|
+
type T = { draft: boolean; readonly items: readonly string[] };
|
|
5457
|
+
`,
|
|
5458
|
+
options: { mutablePropertyPrefixes: ['draft'] },
|
|
5459
|
+
},
|
|
5460
|
+
{
|
|
5461
|
+
name: 'A constructor parameter property is a property',
|
|
5462
|
+
source: dedent`
|
|
5463
|
+
class C {
|
|
5464
|
+
draftA: string[] = [];
|
|
5465
|
+
constructor(private draftB: string[], readonly draftD: string[], draftC: string[]) {}
|
|
5466
|
+
}
|
|
5467
|
+
`,
|
|
5468
|
+
expected: dedent`
|
|
5469
|
+
class C {
|
|
5470
|
+
draftA: string[] = [];
|
|
5471
|
+
constructor(private draftB: string[], readonly draftD: string[], draftC: readonly string[]) {}
|
|
5472
|
+
}
|
|
5473
|
+
`,
|
|
5474
|
+
options: { mutablePropertyPrefixes: ['draft'] },
|
|
5475
|
+
},
|
|
5476
|
+
{
|
|
5477
|
+
name: 'A constructor parameter that is not a property is a variable',
|
|
5478
|
+
source: dedent`
|
|
5479
|
+
class C {
|
|
5480
|
+
draftA: string[] = [];
|
|
5481
|
+
constructor(private draftB: string[], draftC: string[]) {}
|
|
5482
|
+
}
|
|
5198
5483
|
`,
|
|
5199
5484
|
expected: dedent`
|
|
5200
|
-
|
|
5485
|
+
class C {
|
|
5486
|
+
readonly draftA: readonly string[] = [];
|
|
5487
|
+
constructor(private readonly draftB: readonly string[], draftC: string[]) {}
|
|
5488
|
+
}
|
|
5201
5489
|
`,
|
|
5490
|
+
options: { mutableVariablePrefixes: ['draft'] },
|
|
5202
5491
|
},
|
|
5203
5492
|
])('$name', testFn);
|
|
5493
|
+
|
|
5494
|
+
test('the removed ignorePrefixes option is refused', () => {
|
|
5495
|
+
expect(() =>
|
|
5496
|
+
convertToReadonlyTransformer(
|
|
5497
|
+
// @ts-expect-error removed in 4.0.0
|
|
5498
|
+
{ ignorePrefixes: ['mut_'] },
|
|
5499
|
+
),
|
|
5500
|
+
).toThrow('mutableVariablePrefixes');
|
|
5501
|
+
});
|
|
5502
|
+
|
|
5503
|
+
test('an unset ignorePrefixes option is accepted', () => {
|
|
5504
|
+
expect(() =>
|
|
5505
|
+
convertToReadonlyTransformer(
|
|
5506
|
+
// @ts-expect-error removed in 4.0.0
|
|
5507
|
+
{ ignorePrefixes: undefined },
|
|
5508
|
+
),
|
|
5509
|
+
).not.toThrow();
|
|
5510
|
+
});
|
|
5204
5511
|
});
|
|
5205
5512
|
|
|
5206
5513
|
describe('Disable comment handling', () => {
|