ts-codemod-lib 3.3.0 → 3.3.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/README.md +22 -0
- package/dist/entry-point.mjs +2 -24
- package/dist/entry-point.mjs.map +1 -1
- package/dist/functions/ast-transformers/append-as-const.mjs +330 -292
- package/dist/functions/ast-transformers/append-as-const.mjs.map +1 -1
- package/dist/functions/ast-transformers/convert-interface-to-type.mjs +85 -70
- package/dist/functions/ast-transformers/convert-interface-to-type.mjs.map +1 -1
- package/dist/functions/ast-transformers/convert-to-readonly.d.mts.map +1 -1
- package/dist/functions/ast-transformers/convert-to-readonly.mjs +971 -838
- package/dist/functions/ast-transformers/convert-to-readonly.mjs.map +1 -1
- package/dist/functions/ast-transformers/enable-no-unchecked-indexed-access.d.mts +32 -9
- package/dist/functions/ast-transformers/enable-no-unchecked-indexed-access.d.mts.map +1 -1
- package/dist/functions/ast-transformers/enable-no-unchecked-indexed-access.mjs +299 -134
- package/dist/functions/ast-transformers/enable-no-unchecked-indexed-access.mjs.map +1 -1
- package/dist/functions/ast-transformers/index.mjs +10 -12
- package/dist/functions/ast-transformers/index.mjs.map +1 -1
- package/dist/functions/ast-transformers/readonly-transformer-helpers/compare-union-types.mjs +14 -7
- package/dist/functions/ast-transformers/readonly-transformer-helpers/compare-union-types.mjs.map +1 -1
- package/dist/functions/ast-transformers/readonly-transformer-helpers/constants.mjs +12 -15
- package/dist/functions/ast-transformers/readonly-transformer-helpers/constants.mjs.map +1 -1
- package/dist/functions/ast-transformers/readonly-transformer-helpers/group-union-types.d.mts.map +1 -1
- package/dist/functions/ast-transformers/readonly-transformer-helpers/group-union-types.mjs +70 -59
- package/dist/functions/ast-transformers/readonly-transformer-helpers/group-union-types.mjs.map +1 -1
- package/dist/functions/ast-transformers/readonly-transformer-helpers/index.mjs +5 -5
- package/dist/functions/ast-transformers/readonly-transformer-helpers/index.mjs.map +1 -1
- package/dist/functions/ast-transformers/readonly-transformer-helpers/readonly-context.mjs +15 -20
- package/dist/functions/ast-transformers/readonly-transformer-helpers/readonly-context.mjs.map +1 -1
- package/dist/functions/ast-transformers/replace-any-with-unknown.mjs +30 -34
- package/dist/functions/ast-transformers/replace-any-with-unknown.mjs.map +1 -1
- package/dist/functions/ast-transformers/replace-record-with-unknown-record.mjs +197 -156
- package/dist/functions/ast-transformers/replace-record-with-unknown-record.mjs.map +1 -1
- package/dist/functions/ast-transformers/transform-source-code.mjs +74 -75
- package/dist/functions/ast-transformers/transform-source-code.mjs.map +1 -1
- package/dist/functions/ast-transformers/types.mjs +2 -2
- package/dist/functions/ast-transformers/types.mjs.map +1 -1
- package/dist/functions/constants/ignore-comment-text.mjs +11 -13
- package/dist/functions/constants/ignore-comment-text.mjs.map +1 -1
- package/dist/functions/constants/index.mjs +2 -2
- package/dist/functions/constants/index.mjs.map +1 -1
- package/dist/functions/functions/has-call-or-construct-signature.d.mts +18 -0
- package/dist/functions/functions/has-call-or-construct-signature.d.mts.map +1 -0
- package/dist/functions/functions/has-call-or-construct-signature.mjs +87 -0
- package/dist/functions/functions/has-call-or-construct-signature.mjs.map +1 -0
- package/dist/functions/functions/has-disable-next-line-comment.mjs +67 -38
- package/dist/functions/functions/has-disable-next-line-comment.mjs.map +1 -1
- package/dist/functions/functions/index.d.mts +1 -0
- package/dist/functions/functions/index.d.mts.map +1 -1
- package/dist/functions/functions/index.mjs +12 -11
- package/dist/functions/functions/index.mjs.map +1 -1
- package/dist/functions/functions/is-as-const-node.mjs +25 -20
- package/dist/functions/functions/is-as-const-node.mjs.map +1 -1
- package/dist/functions/functions/is-atomic-type-node.mjs +245 -25
- package/dist/functions/functions/is-atomic-type-node.mjs.map +1 -1
- package/dist/functions/functions/is-conditional-type-distribution-guard.mjs +34 -13
- package/dist/functions/functions/is-conditional-type-distribution-guard.mjs.map +1 -1
- package/dist/functions/functions/is-readonly-node.mjs +120 -14
- package/dist/functions/functions/is-readonly-node.mjs.map +1 -1
- package/dist/functions/functions/is-spread-parameter-node.mjs +5 -6
- package/dist/functions/functions/is-spread-parameter-node.mjs.map +1 -1
- package/dist/functions/functions/remove-parentheses.mjs +4 -4
- package/dist/functions/functions/remove-parentheses.mjs.map +1 -1
- package/dist/functions/functions/should-avoid-parentheses-for-readonly.mjs +23 -9
- package/dist/functions/functions/should-avoid-parentheses-for-readonly.mjs.map +1 -1
- package/dist/functions/functions/unwrap-readonly.mjs +3 -4
- package/dist/functions/functions/unwrap-readonly.mjs.map +1 -1
- package/dist/functions/functions/wrap-with-parentheses.d.mts +14 -5
- package/dist/functions/functions/wrap-with-parentheses.d.mts.map +1 -1
- package/dist/functions/functions/wrap-with-parentheses.mjs +67 -30
- package/dist/functions/functions/wrap-with-parentheses.mjs.map +1 -1
- package/dist/functions/index.mjs +5 -24
- package/dist/functions/index.mjs.map +1 -1
- package/dist/functions/utils/index.mjs +2 -2
- package/dist/functions/utils/index.mjs.map +1 -1
- package/dist/functions/utils/replace-with-debug.mjs +4 -6
- package/dist/functions/utils/replace-with-debug.mjs.map +1 -1
- package/dist/index.mjs +2 -24
- package/dist/index.mjs.map +1 -1
- package/package.json +18 -18
- package/src/functions/ast-transformers/convert-to-readonly.mts +19 -13
- package/src/functions/ast-transformers/convert-to-readonly.test.mts +129 -1
- package/src/functions/ast-transformers/enable-no-unchecked-indexed-access.mts +32 -9
- package/src/functions/ast-transformers/enable-no-unchecked-indexed-access.test.mts +76 -22
- package/src/functions/ast-transformers/readonly-transformer-helpers/group-union-types.mts +8 -1
- package/src/functions/functions/has-call-or-construct-signature.mts +120 -0
- package/src/functions/functions/index.mts +1 -0
- package/src/functions/functions/wrap-with-parentheses.mts +32 -17
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unwrap-readonly.mjs","sources":["../../../src/functions/functions/unwrap-readonly.mts"],"
|
|
1
|
+
{"version":3,"file":"unwrap-readonly.mjs","sourceRoot":"","sources":["../../../src/functions/functions/unwrap-readonly.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAElE,MAAM,CAAC,MAAM,yBAAyB,GAAG;AACvC,8EAA8E;AAC9E,IAA+B,EACvB,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC"}
|
|
@@ -4,11 +4,20 @@
|
|
|
4
4
|
* fully wrapped with balanced parentheses.
|
|
5
5
|
*
|
|
6
6
|
* @example
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* wrapWithParentheses('A
|
|
10
|
-
*
|
|
11
|
-
*
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* assert.deepStrictEqual(wrapWithParentheses('A'), '(A)');
|
|
10
|
+
*
|
|
11
|
+
* // already wrapped, so not '((A))'
|
|
12
|
+
* assert.deepStrictEqual(wrapWithParentheses('(A)'), '(A)');
|
|
13
|
+
*
|
|
14
|
+
* assert.deepStrictEqual(wrapWithParentheses('A | B'), '(A | B)');
|
|
15
|
+
*
|
|
16
|
+
* assert.deepStrictEqual(wrapWithParentheses('(A | B)'), '(A | B)');
|
|
17
|
+
*
|
|
18
|
+
* // the outer parentheses do not span everything, so a pair is added
|
|
19
|
+
* assert.deepStrictEqual(wrapWithParentheses('(A) | (B)'), '((A) | (B))');
|
|
20
|
+
* ```
|
|
12
21
|
*/
|
|
13
22
|
export declare const wrapWithParentheses: (nodeStr: string) => string;
|
|
14
23
|
//# sourceMappingURL=wrap-with-parentheses.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wrap-with-parentheses.d.mts","sourceRoot":"","sources":["../../../src/functions/functions/wrap-with-parentheses.mts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"wrap-with-parentheses.d.mts","sourceRoot":"","sources":["../../../src/functions/functions/wrap-with-parentheses.mts"],"names":[],"mappings":"AAsDA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,mBAAmB,YAAa,MAAM,KAAG,MAQrD,CAAC"}
|
|
@@ -1,36 +1,73 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { asUint32, range } from 'ts-data-forge';
|
|
3
2
|
const parenDepthDelta = (char) => {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
3
|
+
switch (char) {
|
|
4
|
+
case '(':
|
|
5
|
+
return 1;
|
|
6
|
+
case ')':
|
|
7
|
+
return -1;
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
case undefined:
|
|
11
|
+
default:
|
|
12
|
+
return 0;
|
|
13
|
+
}
|
|
12
14
|
};
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
13
28
|
const isWrappedWithParentheses = (str) => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
let mut_depth = 0;
|
|
19
|
-
for (const mut_i of range(0, asUint32(trimmed.length))) {
|
|
20
|
-
mut_depth += parenDepthDelta(trimmed.charAt(mut_i));
|
|
21
|
-
if (mut_depth === 0 && mut_i < trimmed.length - 1) {
|
|
22
|
-
return false;
|
|
29
|
+
const trimmed = str.trim();
|
|
30
|
+
if (!trimmed.startsWith('(') || !trimmed.endsWith(')')) {
|
|
31
|
+
return false;
|
|
23
32
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
let mut_depth = 0;
|
|
36
|
+
for (const mut_i of range(0, asUint32(trimmed.length))) {
|
|
37
|
+
mut_depth += parenDepthDelta(trimmed.at(mut_i));
|
|
38
|
+
|
|
39
|
+
if (mut_depth === 0 && mut_i < trimmed.length - 1) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return true;
|
|
33
44
|
};
|
|
34
45
|
|
|
35
|
-
|
|
36
|
-
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
export const wrapWithParentheses = (nodeStr) => {
|
|
67
|
+
const trimmed = nodeStr.trim();
|
|
68
|
+
if (isWrappedWithParentheses(trimmed)) {
|
|
69
|
+
return trimmed;
|
|
70
|
+
}
|
|
71
|
+
return `(${trimmed})`;
|
|
72
|
+
};
|
|
73
|
+
//# sourceMappingURL=wrap-with-parentheses.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wrap-with-parentheses.mjs","sources":["../../../src/functions/functions/wrap-with-parentheses.mts"],"
|
|
1
|
+
{"version":3,"file":"wrap-with-parentheses.mjs","sourceRoot":"","sources":["../../../src/functions/functions/wrap-with-parentheses.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,eAAe,GAAG,CAAC,IAAwB,EAAU,EAAE;IAC3D,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,GAAG;YACN,OAAO,CAAC,CAAC;QAEX,KAAK,GAAG;YACN,OAAO,CAAC,CAAC,CAAC;QAEZ,sEAAsE;QACtE,0DAA0D;QAC1D,KAAK,SAAS,CAAC;QACf;YACE,OAAO,CAAC,CAAC;IACb,CAAC;AACH,CAAC,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,wBAAwB,GAAG,CAAC,GAAW,EAAW,EAAE;IACxD,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAE3B,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACvD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,4DAA4D;IAC5D,6DAA6D;IAC7D,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;QACvD,SAAS,IAAI,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;QAEhD,kFAAkF;QAClF,IAAI,SAAS,KAAK,CAAC,IAAI,KAAK,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClD,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,OAAe,EAAU,EAAE;IAC7D,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAE/B,IAAI,wBAAwB,CAAC,OAAO,CAAC,EAAE,CAAC;QACtC,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,OAAO,IAAI,OAAO,GAAY,CAAC;AACjC,CAAC,CAAC"}
|
package/dist/functions/index.mjs
CHANGED
|
@@ -1,24 +1,5 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
export { invalidDeepReadonlyTypeName } from './ast-transformers/readonly-transformer-helpers/constants.mjs';
|
|
7
|
-
export { groupUnionIntersectionTypes } from './ast-transformers/readonly-transformer-helpers/group-union-types.mjs';
|
|
8
|
-
export { nextReadonlyContext } from './ast-transformers/readonly-transformer-helpers/readonly-context.mjs';
|
|
9
|
-
export { replaceAnyWithUnknownTransformer } from './ast-transformers/replace-any-with-unknown.mjs';
|
|
10
|
-
export { replaceRecordWithUnknownRecordTransformer } from './ast-transformers/replace-record-with-unknown-record.mjs';
|
|
11
|
-
export { transformSourceCode } from './ast-transformers/transform-source-code.mjs';
|
|
12
|
-
export { IGNORE_FILE_COMMENT_PREFIXES, IGNORE_LINE_COMMENT_PREFIXES } from './constants/ignore-comment-text.mjs';
|
|
13
|
-
export { hasDisableNextLineComment } from './functions/has-disable-next-line-comment.mjs';
|
|
14
|
-
export { isAsConstNode } from './functions/is-as-const-node.mjs';
|
|
15
|
-
export { isAtomicTypeNode } from './functions/is-atomic-type-node.mjs';
|
|
16
|
-
export { isConditionalTypeDistributionGuard } from './functions/is-conditional-type-distribution-guard.mjs';
|
|
17
|
-
export { isReadonlyArrayTypeNode, isReadonlyTupleOrArrayTypeNode, isReadonlyTupleTypeNode, isReadonlyTypeReferenceNode, isShallowReadonlyTypeNode } from './functions/is-readonly-node.mjs';
|
|
18
|
-
export { isSpreadNamedTupleMemberNode, isSpreadParameterNode } from './functions/is-spread-parameter-node.mjs';
|
|
19
|
-
export { removeParentheses } from './functions/remove-parentheses.mjs';
|
|
20
|
-
export { shouldAvoidParenthesesForReadonly } from './functions/should-avoid-parentheses-for-readonly.mjs';
|
|
21
|
-
export { unwrapReadonlyTypeArgText } from './functions/unwrap-readonly.mjs';
|
|
22
|
-
export { wrapWithParentheses } from './functions/wrap-with-parentheses.mjs';
|
|
23
|
-
export { replaceNodeWithDebugPrint } from './utils/replace-with-debug.mjs';
|
|
24
|
-
//# sourceMappingURL=index.mjs.map
|
|
1
|
+
export * from './ast-transformers/index.mjs';
|
|
2
|
+
export * from './constants/index.mjs';
|
|
3
|
+
export * from './functions/index.mjs';
|
|
4
|
+
export * from './utils/index.mjs';
|
|
5
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","
|
|
1
|
+
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../src/functions/index.mts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAC;AAC7C,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export
|
|
2
|
-
//# sourceMappingURL=index.mjs.map
|
|
1
|
+
export * from './replace-with-debug.mjs';
|
|
2
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","
|
|
1
|
+
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../../src/functions/utils/index.mts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC"}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
const replaceNodeWithDebugPrint = (node, newNodeText) => {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
export const replaceNodeWithDebugPrint = (node, newNodeText) => {
|
|
2
|
+
console.debug(`${node.getText()} -> ${newNodeText}`);
|
|
3
|
+
node.replaceWithText(newNodeText);
|
|
4
4
|
};
|
|
5
|
-
|
|
6
|
-
export { replaceNodeWithDebugPrint };
|
|
7
|
-
//# sourceMappingURL=replace-with-debug.mjs.map
|
|
5
|
+
//# sourceMappingURL=replace-with-debug.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"replace-with-debug.mjs","sources":["../../../src/functions/utils/replace-with-debug.mts"],"
|
|
1
|
+
{"version":3,"file":"replace-with-debug.mjs","sourceRoot":"","sources":["../../../src/functions/utils/replace-with-debug.mts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,yBAAyB,GAAG,CACvC,IAAc,EACd,WAAmB,EACb,EAAE;IACR,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,EAAE,OAAO,WAAW,EAAE,CAAC,CAAC;IAErD,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;AACpC,CAAC,CAAC"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,24 +1,2 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
export { convertToReadonlyTransformer } from './functions/ast-transformers/convert-to-readonly.mjs';
|
|
4
|
-
export { enableNoUncheckedIndexedAccessTransformer } from './functions/ast-transformers/enable-no-unchecked-indexed-access.mjs';
|
|
5
|
-
export { compareUnionIntersectionTypes } from './functions/ast-transformers/readonly-transformer-helpers/compare-union-types.mjs';
|
|
6
|
-
export { invalidDeepReadonlyTypeName } from './functions/ast-transformers/readonly-transformer-helpers/constants.mjs';
|
|
7
|
-
export { groupUnionIntersectionTypes } from './functions/ast-transformers/readonly-transformer-helpers/group-union-types.mjs';
|
|
8
|
-
export { nextReadonlyContext } from './functions/ast-transformers/readonly-transformer-helpers/readonly-context.mjs';
|
|
9
|
-
export { replaceAnyWithUnknownTransformer } from './functions/ast-transformers/replace-any-with-unknown.mjs';
|
|
10
|
-
export { replaceRecordWithUnknownRecordTransformer } from './functions/ast-transformers/replace-record-with-unknown-record.mjs';
|
|
11
|
-
export { transformSourceCode } from './functions/ast-transformers/transform-source-code.mjs';
|
|
12
|
-
export { IGNORE_FILE_COMMENT_PREFIXES, IGNORE_LINE_COMMENT_PREFIXES } from './functions/constants/ignore-comment-text.mjs';
|
|
13
|
-
export { hasDisableNextLineComment } from './functions/functions/has-disable-next-line-comment.mjs';
|
|
14
|
-
export { isAsConstNode } from './functions/functions/is-as-const-node.mjs';
|
|
15
|
-
export { isAtomicTypeNode } from './functions/functions/is-atomic-type-node.mjs';
|
|
16
|
-
export { isConditionalTypeDistributionGuard } from './functions/functions/is-conditional-type-distribution-guard.mjs';
|
|
17
|
-
export { isReadonlyArrayTypeNode, isReadonlyTupleOrArrayTypeNode, isReadonlyTupleTypeNode, isReadonlyTypeReferenceNode, isShallowReadonlyTypeNode } from './functions/functions/is-readonly-node.mjs';
|
|
18
|
-
export { isSpreadNamedTupleMemberNode, isSpreadParameterNode } from './functions/functions/is-spread-parameter-node.mjs';
|
|
19
|
-
export { removeParentheses } from './functions/functions/remove-parentheses.mjs';
|
|
20
|
-
export { shouldAvoidParenthesesForReadonly } from './functions/functions/should-avoid-parentheses-for-readonly.mjs';
|
|
21
|
-
export { unwrapReadonlyTypeArgText } from './functions/functions/unwrap-readonly.mjs';
|
|
22
|
-
export { wrapWithParentheses } from './functions/functions/wrap-with-parentheses.mjs';
|
|
23
|
-
export { replaceNodeWithDebugPrint } from './functions/utils/replace-with-debug.mjs';
|
|
24
|
-
//# sourceMappingURL=index.mjs.map
|
|
1
|
+
export * from './functions/index.mjs';
|
|
2
|
+
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","
|
|
1
|
+
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.mts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-codemod-lib",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -38,45 +38,44 @@
|
|
|
38
38
|
"LICENSE"
|
|
39
39
|
],
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"ts-data-forge": "^14.
|
|
41
|
+
"ts-data-forge": "^14.7.1",
|
|
42
42
|
"ts-morph": "^28.0.0",
|
|
43
43
|
"ts-type-forge": "^9.2.2"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@types/node": "26.
|
|
47
|
-
"@vitest/browser-playwright": "
|
|
48
|
-
"@vitest/coverage-v8": "
|
|
49
|
-
"@vitest/ui": "
|
|
50
|
-
"cspell": "10.
|
|
46
|
+
"@types/node": "26.5.0",
|
|
47
|
+
"@vitest/browser-playwright": "5.0.0",
|
|
48
|
+
"@vitest/coverage-v8": "5.0.0",
|
|
49
|
+
"@vitest/ui": "5.0.0",
|
|
50
|
+
"cspell": "10.2.1",
|
|
51
51
|
"dedent": "1.7.2",
|
|
52
52
|
"esbuild": "0.28.2",
|
|
53
|
-
"eslint": "10.
|
|
54
|
-
"eslint-config-typed": "5.
|
|
55
|
-
"eslint-plugin-ts-data-forge": "0.
|
|
56
|
-
"eslint-plugin-ts-fortress": "1.
|
|
57
|
-
"eslint-plugin-ts-type-forge": "0.
|
|
53
|
+
"eslint": "10.9.1",
|
|
54
|
+
"eslint-config-typed": "5.11.7",
|
|
55
|
+
"eslint-plugin-ts-data-forge": "0.7.4",
|
|
56
|
+
"eslint-plugin-ts-fortress": "1.2.2",
|
|
57
|
+
"eslint-plugin-ts-type-forge": "0.8.3",
|
|
58
58
|
"jiti": "2.7.0",
|
|
59
59
|
"npm-run-all2": "9.0.3",
|
|
60
60
|
"playwright": "1.62.1",
|
|
61
61
|
"prettier": "3.9.6",
|
|
62
62
|
"prettier-plugin-organize-imports": "4.3.0",
|
|
63
63
|
"prettier-plugin-packagejson": "3.0.2",
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"tsx": "4.23.12",
|
|
64
|
+
"ts-repo-utils": "10.6.2",
|
|
65
|
+
"tsx": "4.23.13",
|
|
67
66
|
"typedoc": "0.28.20",
|
|
68
67
|
"typedoc-github-theme": "0.4.0",
|
|
69
68
|
"typescript": "6.0.3",
|
|
70
69
|
"typescript-native": "npm:typescript@7.0.2",
|
|
71
|
-
"vite": "8.2.
|
|
72
|
-
"vitest": "
|
|
70
|
+
"vite": "8.2.2",
|
|
71
|
+
"vitest": "5.0.0"
|
|
73
72
|
},
|
|
74
73
|
"engines": {
|
|
75
74
|
"node": ">=22.22.2",
|
|
76
75
|
"pnpm": ">=9.0.0"
|
|
77
76
|
},
|
|
78
77
|
"volta": {
|
|
79
|
-
"node": "26.
|
|
78
|
+
"node": "26.8.1"
|
|
80
79
|
},
|
|
81
80
|
"publishConfig": {
|
|
82
81
|
"access": "public",
|
|
@@ -95,6 +94,7 @@
|
|
|
95
94
|
"cspell": "cspell \"**\" --gitignore --gitignore-root ../../ --no-progress",
|
|
96
95
|
"doc": "tsx --tsconfig ../../tools/configs/tsconfig.tsx.json ./scripts/cmd/gen-docs.mts",
|
|
97
96
|
"doc:embed": "tsx --tsconfig ../../tools/configs/tsconfig.tsx.json ./scripts/cmd/embed-examples.mts",
|
|
97
|
+
"doc:embed:jsdoc": "tsx --tsconfig ../../tools/configs/tsconfig.tsx.json ./scripts/cmd/embed-examples-in-jsdoc.mts",
|
|
98
98
|
"doc:preview": "vite preview --config ./configs/vite.doc.config.mts",
|
|
99
99
|
"doc:watch": "typedoc --options ./configs/typedoc.config.mjs --watch",
|
|
100
100
|
"fmt": "tsx --tsconfig ../../tools/configs/tsconfig.tsx.json ../../libs/ts-repo-utils/src/cmd/format-uncommitted.mts --cwd .",
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
type StrictExtract,
|
|
16
16
|
} from 'ts-type-forge';
|
|
17
17
|
import {
|
|
18
|
+
hasCallOrConstructSignature,
|
|
18
19
|
hasDisableNextLineComment,
|
|
19
20
|
isAtomicTypeNode,
|
|
20
21
|
isConditionalTypeDistributionGuard,
|
|
@@ -1032,10 +1033,24 @@ const transformTypeLiteralNode = (
|
|
|
1032
1033
|
return;
|
|
1033
1034
|
}
|
|
1034
1035
|
|
|
1036
|
+
// Whether this position is one where the literal is wrapped at all — a
|
|
1037
|
+
// context that already carries `Readonly` or `DeepReadonly` does it, and
|
|
1038
|
+
// inside an indexed access the modifier makes no difference to the result.
|
|
1039
|
+
const wrappingApplies =
|
|
1040
|
+
readonlyContext.type === 'none' && readonlyContext.indexedAccessDepth === 0;
|
|
1041
|
+
|
|
1042
|
+
// A call or construct signature does not survive `Readonly<T>`, so a literal
|
|
1043
|
+
// carrying one is left unwrapped and marked readonly member by member
|
|
1044
|
+
// instead. See `hasCallOrConstructSignature`.
|
|
1045
|
+
const skipWrapping = wrappingApplies && hasCallOrConstructSignature(node);
|
|
1046
|
+
|
|
1035
1047
|
// Recursive processing
|
|
1036
1048
|
transformMembers(
|
|
1037
1049
|
node.getMembers(),
|
|
1038
|
-
|
|
1050
|
+
// A wrapper — the one added below, or the one the context already carries —
|
|
1051
|
+
// is what makes the members readonly, so an inner modifier would be
|
|
1052
|
+
// redundant. Without one, each member has to say so itself.
|
|
1053
|
+
skipWrapping ? 'add' : 'remove',
|
|
1039
1054
|
nextReadonlyContext({
|
|
1040
1055
|
currentReadonlyContext: readonlyContext,
|
|
1041
1056
|
nextReadonlyContextType: 'none',
|
|
@@ -1044,18 +1059,9 @@ const transformTypeLiteralNode = (
|
|
|
1044
1059
|
options,
|
|
1045
1060
|
);
|
|
1046
1061
|
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
// Don't wrap with Readonly if already readonly
|
|
1051
|
-
return;
|
|
1052
|
-
|
|
1053
|
-
case 'none': {
|
|
1054
|
-
if (readonlyContext.indexedAccessDepth === 0) {
|
|
1055
|
-
// `{ readonly x: X, readonly y: Y } |-> Readonly<{ x: X, y: Y }>`
|
|
1056
|
-
options.replaceNode(node, `Readonly<${node.getFullText()}>`);
|
|
1057
|
-
}
|
|
1058
|
-
}
|
|
1062
|
+
if (wrappingApplies && !skipWrapping) {
|
|
1063
|
+
// `{ readonly x: X, readonly y: Y } |-> Readonly<{ x: X, y: Y }>`
|
|
1064
|
+
options.replaceNode(node, `Readonly<${node.getFullText()}>`);
|
|
1059
1065
|
}
|
|
1060
1066
|
};
|
|
1061
1067
|
|
|
@@ -6,6 +6,7 @@ import dedent from 'dedent';
|
|
|
6
6
|
import * as prettierPluginEstree from 'prettier/plugins/estree';
|
|
7
7
|
import * as prettierPluginTypeScript from 'prettier/plugins/typescript';
|
|
8
8
|
import * as prettier from 'prettier/standalone';
|
|
9
|
+
import { isString } from 'ts-data-forge';
|
|
9
10
|
import {
|
|
10
11
|
convertToReadonlyTransformer,
|
|
11
12
|
type ReadonlyTransformerOptions,
|
|
@@ -63,7 +64,15 @@ const normalizeWhitespaceForComparison = (code: string): string => {
|
|
|
63
64
|
// 1. Protect newlines immediately following line comments
|
|
64
65
|
const protectedCode = code.replaceAll(
|
|
65
66
|
/(\/\/.*?)\r?\n/gu,
|
|
66
|
-
|
|
67
|
+
// The strict standard library types a capture group as `unknown`: an
|
|
68
|
+
// optional group is `undefined` when it does not participate, so `string`
|
|
69
|
+
// is not something the signature can promise. This group is not optional,
|
|
70
|
+
// so the narrowing never actually fails — it just has to be written.
|
|
71
|
+
(match: string, ...args: readonly unknown[]): string => {
|
|
72
|
+
const comment = args[0];
|
|
73
|
+
|
|
74
|
+
return isString(comment) ? `${comment}${placeholder}` : match;
|
|
75
|
+
},
|
|
67
76
|
);
|
|
68
77
|
|
|
69
78
|
// 2. Collapse multiple whitespace characters (including unprotected newlines) into a single space
|
|
@@ -3246,6 +3255,125 @@ describe(convertToReadonlyTransformer, () => {
|
|
|
3246
3255
|
])('$name', testFn);
|
|
3247
3256
|
});
|
|
3248
3257
|
|
|
3258
|
+
describe('Call and construct signatures', () => {
|
|
3259
|
+
// `Readonly<T>` is a mapped type over `keyof T`, and a call or construct
|
|
3260
|
+
// signature is not a property, so wrapping a type literal that carries one
|
|
3261
|
+
// silently drops it — the value stops being callable. See #1881.
|
|
3262
|
+
test.each([
|
|
3263
|
+
{
|
|
3264
|
+
name: 'Overloaded call signatures are not wrapped',
|
|
3265
|
+
source: dedent`
|
|
3266
|
+
const panic: {
|
|
3267
|
+
(message: string, options?: { cause?: unknown }): never;
|
|
3268
|
+
(error: Error): never;
|
|
3269
|
+
} = impl;
|
|
3270
|
+
`,
|
|
3271
|
+
expected: dedent`
|
|
3272
|
+
const panic: {
|
|
3273
|
+
(message: string, options?: Readonly<{ cause?: unknown }>): never;
|
|
3274
|
+
(error: Error): never;
|
|
3275
|
+
} = impl;
|
|
3276
|
+
`,
|
|
3277
|
+
},
|
|
3278
|
+
{
|
|
3279
|
+
name: 'A single call signature is not wrapped',
|
|
3280
|
+
source: dedent`
|
|
3281
|
+
type F = { (arg: number[]): string[] };
|
|
3282
|
+
`,
|
|
3283
|
+
expected: dedent`
|
|
3284
|
+
type F = { (arg: readonly number[]): readonly string[] };
|
|
3285
|
+
`,
|
|
3286
|
+
},
|
|
3287
|
+
{
|
|
3288
|
+
name: 'A construct signature is not wrapped',
|
|
3289
|
+
source: dedent`
|
|
3290
|
+
type C = { new (arg: string[]): { prop: number[] } };
|
|
3291
|
+
`,
|
|
3292
|
+
expected: dedent`
|
|
3293
|
+
type C = { new (arg: readonly string[]): Readonly<{ prop: readonly number[] }> };
|
|
3294
|
+
`,
|
|
3295
|
+
},
|
|
3296
|
+
{
|
|
3297
|
+
name: 'Members alongside a call signature are marked readonly in place',
|
|
3298
|
+
source: dedent`
|
|
3299
|
+
type F = {
|
|
3300
|
+
(arg: number[]): void;
|
|
3301
|
+
prop: string[];
|
|
3302
|
+
[key: string]: unknown;
|
|
3303
|
+
};
|
|
3304
|
+
`,
|
|
3305
|
+
expected: dedent`
|
|
3306
|
+
type F = {
|
|
3307
|
+
(arg: readonly number[]): void;
|
|
3308
|
+
readonly prop: readonly string[];
|
|
3309
|
+
readonly [key: string]: unknown;
|
|
3310
|
+
};
|
|
3311
|
+
`,
|
|
3312
|
+
},
|
|
3313
|
+
{
|
|
3314
|
+
name: 'Members alongside a construct signature are marked readonly in place',
|
|
3315
|
+
source: dedent`
|
|
3316
|
+
type C = {
|
|
3317
|
+
new (arg: string[]): unknown;
|
|
3318
|
+
readonly prop: number[];
|
|
3319
|
+
};
|
|
3320
|
+
`,
|
|
3321
|
+
expected: dedent`
|
|
3322
|
+
type C = {
|
|
3323
|
+
new (arg: readonly string[]): unknown;
|
|
3324
|
+
readonly prop: readonly number[];
|
|
3325
|
+
};
|
|
3326
|
+
`,
|
|
3327
|
+
},
|
|
3328
|
+
{
|
|
3329
|
+
name: 'A callable type literal in a union is left alone',
|
|
3330
|
+
source: dedent`
|
|
3331
|
+
type T = { (): void } | { a: number[] };
|
|
3332
|
+
`,
|
|
3333
|
+
expected: dedent`
|
|
3334
|
+
type T = { (): void } | Readonly<{ a: readonly number[] }>;
|
|
3335
|
+
`,
|
|
3336
|
+
},
|
|
3337
|
+
{
|
|
3338
|
+
name: 'A callable type literal in an intersection is left alone',
|
|
3339
|
+
source: dedent`
|
|
3340
|
+
type T = { (): void } & { a: number[] };
|
|
3341
|
+
`,
|
|
3342
|
+
expected: dedent`
|
|
3343
|
+
type T = { (): void } & Readonly<{ a: readonly number[] }>;
|
|
3344
|
+
`,
|
|
3345
|
+
},
|
|
3346
|
+
{
|
|
3347
|
+
name: 'A nested callable type literal is left alone',
|
|
3348
|
+
source: dedent`
|
|
3349
|
+
type T = { fn: { (): void }; a: number[] };
|
|
3350
|
+
`,
|
|
3351
|
+
expected: dedent`
|
|
3352
|
+
type T = Readonly<{ fn: { (): void }; a: readonly number[] }>;
|
|
3353
|
+
`,
|
|
3354
|
+
},
|
|
3355
|
+
])('$name', testFn);
|
|
3356
|
+
|
|
3357
|
+
test('a callable type literal reaches a fixed point', () => {
|
|
3358
|
+
const code = dedent`
|
|
3359
|
+
const panic: {
|
|
3360
|
+
(message: string, options?: { cause?: unknown }): never;
|
|
3361
|
+
(error: Error): never;
|
|
3362
|
+
} = impl;
|
|
3363
|
+
`;
|
|
3364
|
+
|
|
3365
|
+
const once = transformSourceCode(code, false, [
|
|
3366
|
+
convertToReadonlyTransformer(),
|
|
3367
|
+
]);
|
|
3368
|
+
|
|
3369
|
+
const twice = transformSourceCode(once, false, [
|
|
3370
|
+
convertToReadonlyTransformer(),
|
|
3371
|
+
]);
|
|
3372
|
+
|
|
3373
|
+
expect(twice).toBe(once);
|
|
3374
|
+
});
|
|
3375
|
+
});
|
|
3376
|
+
|
|
3249
3377
|
describe('Generic Types', () => {
|
|
3250
3378
|
test.each([
|
|
3251
3379
|
{
|
|
@@ -37,17 +37,40 @@ const TRANSFORMER_NAME = 'enable-no-unchecked-indexed-access';
|
|
|
37
37
|
* as the `if` of `const v = xs[0]!; if (v === undefined) …` now is.
|
|
38
38
|
*
|
|
39
39
|
* @example
|
|
40
|
+
*
|
|
40
41
|
* ```ts
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
42
|
+
* const before = dedent`
|
|
43
|
+
* declare const xs: readonly number[];
|
|
44
|
+
* declare const pair: readonly [number, number];
|
|
45
|
+
* declare const rec: Record<string, number>;
|
|
46
|
+
* declare const known: { a: number };
|
|
47
|
+
*
|
|
48
|
+
* xs[0].toFixed();
|
|
49
|
+
* rec['a'].toFixed();
|
|
50
|
+
* rec.a.toFixed();
|
|
51
|
+
* pair[1].toFixed();
|
|
52
|
+
* known.a.toFixed();
|
|
53
|
+
* `;
|
|
54
|
+
*
|
|
55
|
+
* const after = transformSourceCode(before, false, [
|
|
56
|
+
* enableNoUncheckedIndexedAccessTransformer(),
|
|
57
|
+
* ]);
|
|
58
|
+
*
|
|
59
|
+
* assert.deepStrictEqual(
|
|
60
|
+
* after.trim(),
|
|
61
|
+
* dedent`
|
|
62
|
+
* declare const xs: readonly number[];
|
|
63
|
+
* declare const pair: readonly [number, number];
|
|
64
|
+
* declare const rec: Record<string, number>;
|
|
65
|
+
* declare const known: { a: number };
|
|
45
66
|
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
67
|
+
* xs[0]!.toFixed();
|
|
68
|
+
* rec['a']!.toFixed();
|
|
69
|
+
* rec.a!.toFixed();
|
|
70
|
+
* pair[1].toFixed();
|
|
71
|
+
* known.a.toFixed();
|
|
72
|
+
* `,
|
|
73
|
+
* );
|
|
51
74
|
* ```
|
|
52
75
|
*/
|
|
53
76
|
export const enableNoUncheckedIndexedAccessTransformer = (
|