ts-codemod-lib 2.2.1 → 2.2.3

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 (94) hide show
  1. package/dist/cmd/append-as-const.mjs +51 -48
  2. package/dist/cmd/append-as-const.mjs.map +1 -1
  3. package/dist/cmd/convert-interface-to-type.mjs +51 -48
  4. package/dist/cmd/convert-interface-to-type.mjs.map +1 -1
  5. package/dist/cmd/convert-to-readonly.mjs +51 -48
  6. package/dist/cmd/convert-to-readonly.mjs.map +1 -1
  7. package/dist/cmd/replace-any-with-unknown.mjs +51 -48
  8. package/dist/cmd/replace-any-with-unknown.mjs.map +1 -1
  9. package/dist/cmd/replace-record-with-unknown-record.mjs +51 -48
  10. package/dist/cmd/replace-record-with-unknown-record.mjs.map +1 -1
  11. package/dist/cmd/run-transformer-cli.d.mts.map +1 -1
  12. package/dist/cmd/run-transformer-cli.mjs +138 -127
  13. package/dist/cmd/run-transformer-cli.mjs.map +1 -1
  14. package/dist/functions/ast-transformers/append-as-const.d.mts.map +1 -1
  15. package/dist/functions/ast-transformers/append-as-const.mjs +205 -191
  16. package/dist/functions/ast-transformers/append-as-const.mjs.map +1 -1
  17. package/dist/functions/ast-transformers/convert-interface-to-type.mjs +62 -82
  18. package/dist/functions/ast-transformers/convert-interface-to-type.mjs.map +1 -1
  19. package/dist/functions/ast-transformers/convert-to-readonly.d.mts.map +1 -1
  20. package/dist/functions/ast-transformers/convert-to-readonly.mjs +742 -834
  21. package/dist/functions/ast-transformers/convert-to-readonly.mjs.map +1 -1
  22. package/dist/functions/ast-transformers/readonly-transformer-helpers/compare-union-types.d.mts.map +1 -1
  23. package/dist/functions/ast-transformers/readonly-transformer-helpers/compare-union-types.mjs +2 -14
  24. package/dist/functions/ast-transformers/readonly-transformer-helpers/compare-union-types.mjs.map +1 -1
  25. package/dist/functions/ast-transformers/readonly-transformer-helpers/constants.d.mts +2 -1
  26. package/dist/functions/ast-transformers/readonly-transformer-helpers/constants.d.mts.map +1 -1
  27. package/dist/functions/ast-transformers/readonly-transformer-helpers/constants.mjs +8 -8
  28. package/dist/functions/ast-transformers/readonly-transformer-helpers/constants.mjs.map +1 -1
  29. package/dist/functions/ast-transformers/readonly-transformer-helpers/group-union-types.d.mts.map +1 -1
  30. package/dist/functions/ast-transformers/readonly-transformer-helpers/group-union-types.mjs +51 -62
  31. package/dist/functions/ast-transformers/readonly-transformer-helpers/group-union-types.mjs.map +1 -1
  32. package/dist/functions/ast-transformers/readonly-transformer-helpers/readonly-context.d.mts +12 -12
  33. package/dist/functions/ast-transformers/readonly-transformer-helpers/readonly-context.d.mts.map +1 -1
  34. package/dist/functions/ast-transformers/readonly-transformer-helpers/readonly-context.mjs +16 -14
  35. package/dist/functions/ast-transformers/readonly-transformer-helpers/readonly-context.mjs.map +1 -1
  36. package/dist/functions/ast-transformers/replace-any-with-unknown.mjs +25 -27
  37. package/dist/functions/ast-transformers/replace-any-with-unknown.mjs.map +1 -1
  38. package/dist/functions/ast-transformers/replace-record-with-unknown-record.mjs +149 -208
  39. package/dist/functions/ast-transformers/replace-record-with-unknown-record.mjs.map +1 -1
  40. package/dist/functions/ast-transformers/transform-source-code.d.mts.map +1 -1
  41. package/dist/functions/ast-transformers/transform-source-code.mjs +70 -72
  42. package/dist/functions/ast-transformers/transform-source-code.mjs.map +1 -1
  43. package/dist/functions/constants/ignore-comment-text.d.mts +2 -2
  44. package/dist/functions/constants/ignore-comment-text.d.mts.map +1 -1
  45. package/dist/functions/constants/ignore-comment-text.mjs +8 -8
  46. package/dist/functions/constants/ignore-comment-text.mjs.map +1 -1
  47. package/dist/functions/functions/has-disable-next-line-comment.d.mts.map +1 -1
  48. package/dist/functions/functions/has-disable-next-line-comment.mjs +33 -65
  49. package/dist/functions/functions/has-disable-next-line-comment.mjs.map +1 -1
  50. package/dist/functions/functions/is-as-const-node.d.mts +1 -1
  51. package/dist/functions/functions/is-as-const-node.d.mts.map +1 -1
  52. package/dist/functions/functions/is-as-const-node.mjs +15 -23
  53. package/dist/functions/functions/is-as-const-node.mjs.map +1 -1
  54. package/dist/functions/functions/is-atomic-type-node.d.mts.map +1 -1
  55. package/dist/functions/functions/is-atomic-type-node.mjs +22 -36
  56. package/dist/functions/functions/is-atomic-type-node.mjs.map +1 -1
  57. package/dist/functions/functions/is-conditional-type-distribution-guard.d.mts.map +1 -1
  58. package/dist/functions/functions/is-conditional-type-distribution-guard.mjs +9 -33
  59. package/dist/functions/functions/is-conditional-type-distribution-guard.mjs.map +1 -1
  60. package/dist/functions/functions/is-readonly-node.d.mts.map +1 -1
  61. package/dist/functions/functions/is-readonly-node.mjs +11 -21
  62. package/dist/functions/functions/is-readonly-node.mjs.map +1 -1
  63. package/dist/functions/functions/is-spread-parameter-node.d.mts.map +1 -1
  64. package/dist/functions/functions/is-spread-parameter-node.mjs +2 -4
  65. package/dist/functions/functions/is-spread-parameter-node.mjs.map +1 -1
  66. package/dist/functions/functions/remove-parentheses.d.mts.map +1 -1
  67. package/dist/functions/functions/remove-parentheses.mjs +1 -4
  68. package/dist/functions/functions/remove-parentheses.mjs.map +1 -1
  69. package/dist/functions/functions/should-avoid-parentheses-for-readonly.d.mts.map +1 -1
  70. package/dist/functions/functions/should-avoid-parentheses-for-readonly.mjs +7 -24
  71. package/dist/functions/functions/should-avoid-parentheses-for-readonly.mjs.map +1 -1
  72. package/dist/functions/functions/unwrap-readonly.d.mts.map +1 -1
  73. package/dist/functions/functions/unwrap-readonly.mjs +1 -3
  74. package/dist/functions/functions/unwrap-readonly.mjs.map +1 -1
  75. package/dist/functions/functions/wrap-with-parentheses.d.mts.map +1 -1
  76. package/dist/functions/functions/wrap-with-parentheses.mjs +26 -51
  77. package/dist/functions/functions/wrap-with-parentheses.mjs.map +1 -1
  78. package/dist/functions/utils/replace-with-debug.d.mts.map +1 -1
  79. package/dist/functions/utils/replace-with-debug.mjs +2 -2
  80. package/dist/functions/utils/replace-with-debug.mjs.map +1 -1
  81. package/package.json +40 -29
  82. package/src/cmd/append-as-const.mts +3 -3
  83. package/src/cmd/convert-interface-to-type.mts +3 -3
  84. package/src/cmd/convert-to-readonly.mts +3 -3
  85. package/src/cmd/replace-any-with-unknown.mts +3 -3
  86. package/src/cmd/replace-record-with-unknown-record.mts +3 -3
  87. package/src/cmd/run-transformer-cli.mts +21 -17
  88. package/src/functions/ast-transformers/convert-interface-to-type.mts +1 -1
  89. package/src/functions/ast-transformers/convert-to-readonly.mts +64 -35
  90. package/src/functions/ast-transformers/convert-to-readonly.test.mts +67 -1
  91. package/src/functions/ast-transformers/readonly-transformer-helpers/readonly-context.mts +6 -6
  92. package/src/functions/ast-transformers/replace-record-with-unknown-record.mts +4 -4
  93. package/src/functions/functions/has-disable-next-line-comment.mts +5 -5
  94. package/src/functions/functions/wrap-with-parentheses.mts +17 -23
@@ -1,39 +1,15 @@
1
1
  import * as tsm from 'ts-morph';
2
2
 
3
- /**
4
- * Determines whether a type node is an operand (check or extends type) of a
5
- * conditional type whose check type is wrapped to suppress union distribution,
6
- * i.e. the `X` and `Y` in `X extends Y ? ... : ...` where `X` is itself a tuple
7
- * or array.
8
- *
9
- * Wrapping a naked type parameter so that it is no longer naked is a well-known
10
- * type-implementation idiom used to suppress union distribution. Both
11
- * `[A] extends [B] ? ...` (tuple wrapping) and `A[] extends B[] ? ...` (array
12
- * wrapping) rely on this. Adding a `readonly` modifier to those operands neither
13
- * makes the type more immutable in any meaningful way nor preserves the idiom's
14
- * intent, so such operands must be left untouched.
15
- *
16
- * A naked check type such as `T extends string[] ? ...` still distributes, so it
17
- * is not a guard; arrays/tuples in its extends position are converted as usual.
18
- *
19
- * @param node - The type node to check
20
- * @returns true if the node is the check or extends type of a distribution-guarded
21
- * conditional type
22
- */
23
3
  const isConditionalTypeDistributionGuard = (node) => {
24
- const parent = node.getParent();
25
- if (parent?.isKind(tsm.SyntaxKind.ConditionalType) !== true) {
26
- return false;
27
- }
28
- const checkType = parent.getCheckType();
29
- // The guard is only in effect when the check type itself is wrapped in a tuple
30
- // or array; otherwise (e.g. a naked `T`) the conditional still distributes.
31
- if (!checkType.isKind(tsm.SyntaxKind.TupleType) &&
32
- !checkType.isKind(tsm.SyntaxKind.ArrayType)) {
33
- return false;
34
- }
35
- return (checkType.compilerNode === node.compilerNode ||
36
- parent.getExtendsType().compilerNode === node.compilerNode);
4
+ const parent = node.getParent();
5
+ if (parent?.isKind(tsm.SyntaxKind.ConditionalType) !== true) {
6
+ return false;
7
+ }
8
+ const checkType = parent.getCheckType();
9
+ if (!checkType.isKind(tsm.SyntaxKind.TupleType) && !checkType.isKind(tsm.SyntaxKind.ArrayType)) {
10
+ return false;
11
+ }
12
+ return checkType.compilerNode === node.compilerNode || parent.getExtendsType().compilerNode === node.compilerNode;
37
13
  };
38
14
 
39
15
  export { isConditionalTypeDistributionGuard };
@@ -1 +1 @@
1
- {"version":3,"file":"is-conditional-type-distribution-guard.mjs","sources":["../../../src/functions/functions/is-conditional-type-distribution-guard.mts"],"sourcesContent":[null],"names":[],"mappings":";;AAEA;;;;;;;;;;;;;;;;;;;AAmBG;AACI,MAAM,kCAAkC,GAAG,CAAC,IAAc,KAAa;AAC5E,IAAA,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE;AAE/B,IAAA,IAAI,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,eAAe,CAAC,KAAK,IAAI,EAAE;AAC3D,QAAA,OAAO,KAAK;IACd;AAEA,IAAA,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,EAAE;;;IAIvC,IACE,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC;QAC3C,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,EAC3C;AACA,QAAA,OAAO,KAAK;IACd;AAEA,IAAA,QACE,SAAS,CAAC,YAAY,KAAK,IAAI,CAAC,YAAY;QAC5C,MAAM,CAAC,cAAc,EAAE,CAAC,YAAY,KAAK,IAAI,CAAC,YAAY;AAE9D;;;;"}
1
+ {"version":3,"file":"is-conditional-type-distribution-guard.mjs","sources":["../../../src/functions/functions/is-conditional-type-distribution-guard.mts"],"sourcesContent":["import * as tsm from 'ts-morph';\n\n/**\n * Determines whether a type node is an operand (check or extends type) of a\n * conditional type whose check type is wrapped to suppress union distribution,\n * i.e. the `X` and `Y` in `X extends Y ? ... : ...` where `X` is itself a tuple\n * or array.\n *\n * Wrapping a naked type parameter so that it is no longer naked is a well-known\n * type-implementation idiom used to suppress union distribution. Both\n * `[A] extends [B] ? ...` (tuple wrapping) and `A[] extends B[] ? ...` (array\n * wrapping) rely on this. Adding a `readonly` modifier to those operands neither\n * makes the type more immutable in any meaningful way nor preserves the idiom's\n * intent, so such operands must be left untouched.\n *\n * A naked check type such as `T extends string[] ? ...` still distributes, so it\n * is not a guard; arrays/tuples in its extends position are converted as usual.\n *\n * @param node - The type node to check\n * @returns true if the node is the check or extends type of a distribution-guarded\n * conditional type\n */\nexport const isConditionalTypeDistributionGuard = (node: tsm.Node): boolean => {\n const parent = node.getParent();\n\n if (parent?.isKind(tsm.SyntaxKind.ConditionalType) !== true) {\n return false;\n }\n\n const checkType = parent.getCheckType();\n\n // The guard is only in effect when the check type itself is wrapped in a tuple\n // or array; otherwise (e.g. a naked `T`) the conditional still distributes.\n if (\n !checkType.isKind(tsm.SyntaxKind.TupleType) &&\n !checkType.isKind(tsm.SyntaxKind.ArrayType)\n ) {\n return false;\n }\n\n return (\n checkType.compilerNode === node.compilerNode ||\n parent.getExtendsType().compilerNode === node.compilerNode\n );\n};\n"],"names":[],"mappings":";;AAsBO,MAAM,kCAAA,GAAqC,CAAC,IAAA,KAA4B;AAC7E,EAAA,MAAM,MAAA,GAAS,KAAK,SAAA,EAAU;AAE9B,EAAA,IAAI,QAAQ,MAAA,CAAO,GAAA,CAAI,UAAA,CAAW,eAAe,MAAM,IAAA,EAAM;AAC3D,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,MAAM,SAAA,GAAY,OAAO,YAAA,EAAa;AAItC,EAAA,IACE,CAAC,SAAA,CAAU,MAAA,CAAO,GAAA,CAAI,UAAA,CAAW,SAAS,CAAA,IAC1C,CAAC,SAAA,CAAU,MAAA,CAAO,GAAA,CAAI,UAAA,CAAW,SAAS,CAAA,EAC1C;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,OACE,SAAA,CAAU,iBAAiB,IAAA,CAAK,YAAA,IAChC,OAAO,cAAA,EAAe,CAAE,iBAAiB,IAAA,CAAK,YAAA;AAElD;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"is-readonly-node.d.mts","sourceRoot":"","sources":["../../../src/functions/functions/is-readonly-node.mts"],"names":[],"mappings":"AACA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAGlD,eAAO,MAAM,yBAAyB,GAAI,MAAM,GAAG,CAAC,IAAI,KAAG,OAGnC,CAAC;AAEzB,eAAO,MAAM,8BAA8B,GACzC,MAAM,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,KAC3B,IAAI,IAAI,qBAAqB,GAAG,qBAIqB,CAAC;AAEzD,MAAM,MAAM,qBAAqB,GAAG,GAAG,CAAC,QAAQ,GAC9C,IAAI,CAAC,GAAG,CAAC,oBAAoB,EAAE,aAAa,GAAG,aAAa,CAAC,GAC7D,QAAQ,CAAC;IACP,WAAW,EAAE,MAAM,GAAG,CAAC,UAAU,CAAC,eAAe,CAAC;IAClD,WAAW,EAAE,MAAM,GAAG,CAAC,aAAa,CAAC;CACtC,CAAC,CAAC;AAEL,eAAO,MAAM,uBAAuB,GAClC,MAAM,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,KAC3B,IAAI,IAAI,qBAG0C,CAAC;AA8DtD,MAAM,MAAM,qBAAqB,GAAG,GAAG,CAAC,QAAQ,GAC9C,IAAI,CAAC,GAAG,CAAC,oBAAoB,EAAE,aAAa,GAAG,aAAa,CAAC,GAC7D,QAAQ,CAAC;IACP,WAAW,EAAE,MAAM,GAAG,CAAC,UAAU,CAAC,eAAe,CAAC;IAClD,WAAW,EAAE,MAAM,GAAG,CAAC,aAAa,CAAC;CACtC,CAAC,CAAC;AAEL,eAAO,MAAM,uBAAuB,GAClC,MAAM,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,KAC3B,IAAI,IAAI,qBAG0C,CAAC;AAkDtD,MAAM,MAAM,yBAAyB,GAAG,GAAG,CAAC,QAAQ,GAClD,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,aAAa,GAAG,kBAAkB,CAAC,GAC/D,QAAQ,CAAC;IACP,WAAW,EAAE,MAAM,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,SAAS,CAAC,GAChD,QAAQ,CAAC;QACP,OAAO,EAAE,MAAM,UAAU,CAAC;KAC3B,CAAC,CAAC;IACL,gBAAgB,EAAE,MAAM,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;CACjD,CAAC,CAAC;AAEL,eAAO,MAAM,2BAA2B,GACtC,MAAM,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,KAC3B,IAAI,IAAI,yBAcV,CAAC"}
1
+ {"version":3,"file":"is-readonly-node.d.mts","sourceRoot":"","sources":["../../../src/functions/functions/is-readonly-node.mts"],"names":[],"mappings":"AACA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAGlD,eAAO,MAAM,yBAAyB,SAAU,GAAG,CAAC,IAAI,KAAG,OAGnC,CAAC;AAEzB,eAAO,MAAM,8BAA8B,SACnC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,KAC3B,IAAI,IAAI,qBAAqB,GAAG,qBAIqB,CAAC;AAEzD,MAAM,MAAM,qBAAqB,GAAG,GAAG,CAAC,QAAQ,GAC9C,IAAI,CAAC,GAAG,CAAC,oBAAoB,EAAE,aAAa,GAAG,aAAa,CAAC,GAC7D,QAAQ,CAAC;IACP,WAAW,EAAE,MAAM,GAAG,CAAC,UAAU,CAAC,eAAe,CAAC;IAClD,WAAW,EAAE,MAAM,GAAG,CAAC,aAAa,CAAC;CACtC,CAAC,CAAC;AAEL,eAAO,MAAM,uBAAuB,SAC5B,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,KAC3B,IAAI,IAAI,qBAG0C,CAAC;AA8DtD,MAAM,MAAM,qBAAqB,GAAG,GAAG,CAAC,QAAQ,GAC9C,IAAI,CAAC,GAAG,CAAC,oBAAoB,EAAE,aAAa,GAAG,aAAa,CAAC,GAC7D,QAAQ,CAAC;IACP,WAAW,EAAE,MAAM,GAAG,CAAC,UAAU,CAAC,eAAe,CAAC;IAClD,WAAW,EAAE,MAAM,GAAG,CAAC,aAAa,CAAC;CACtC,CAAC,CAAC;AAEL,eAAO,MAAM,uBAAuB,SAC5B,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,KAC3B,IAAI,IAAI,qBAG0C,CAAC;AAkDtD,MAAM,MAAM,yBAAyB,GAAG,GAAG,CAAC,QAAQ,GAClD,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,aAAa,GAAG,kBAAkB,CAAC,GAC/D,QAAQ,CAAC;IACP,WAAW,EAAE,MAAM,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,SAAS,CAAC,GAChD,QAAQ,CAAC;QACP,OAAO,EAAE,MAAM,UAAU,CAAC;KAC3B,CAAC,CAAC;IACL,gBAAgB,EAAE,MAAM,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;CACjD,CAAC,CAAC;AAEL,eAAO,MAAM,2BAA2B,SAChC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,KAC3B,IAAI,IAAI,yBAcV,CAAC"}
@@ -2,28 +2,18 @@ import { Arr } from 'ts-data-forge';
2
2
  import * as tsm from 'ts-morph';
3
3
  import { isAtomicTypeNode } from './is-atomic-type-node.mjs';
4
4
 
5
- const isShallowReadonlyTypeNode = (node) => isReadonlyTupleOrArrayTypeNode(node) ||
6
- isReadonlyTypeReferenceNode(node) ||
7
- isAtomicTypeNode(node);
8
- const isReadonlyTupleOrArrayTypeNode = (node) => node.isKind(tsm.SyntaxKind.TypeOperator) &&
9
- node.getOperator() === tsm.SyntaxKind.ReadonlyKeyword &&
10
- (node.getTypeNode().isKind(tsm.SyntaxKind.ArrayType) || // Use optional chaining and isKind
11
- node.getTypeNode().isKind(tsm.SyntaxKind.TupleType));
12
- const isReadonlyArrayTypeNode = (node) => node.isKind(tsm.SyntaxKind.TypeOperator) &&
13
- node.getOperator() === tsm.SyntaxKind.ReadonlyKeyword &&
14
- node.getTypeNode().isKind(tsm.SyntaxKind.ArrayType);
15
- const isReadonlyTupleTypeNode = (node) => node.isKind(tsm.SyntaxKind.TypeOperator) &&
16
- node.getOperator() === tsm.SyntaxKind.ReadonlyKeyword &&
17
- node.getTypeNode().isKind(tsm.SyntaxKind.TupleType);
5
+ const isShallowReadonlyTypeNode = (node) => isReadonlyTupleOrArrayTypeNode(node) || isReadonlyTypeReferenceNode(node) || isAtomicTypeNode(node);
6
+ const isReadonlyTupleOrArrayTypeNode = (node) => node.isKind(tsm.SyntaxKind.TypeOperator) && node.getOperator() === tsm.SyntaxKind.ReadonlyKeyword && (node.getTypeNode().isKind(tsm.SyntaxKind.ArrayType) || // Use optional chaining and isKind
7
+ node.getTypeNode().isKind(tsm.SyntaxKind.TupleType));
8
+ const isReadonlyArrayTypeNode = (node) => node.isKind(tsm.SyntaxKind.TypeOperator) && node.getOperator() === tsm.SyntaxKind.ReadonlyKeyword && node.getTypeNode().isKind(tsm.SyntaxKind.ArrayType);
9
+ const isReadonlyTupleTypeNode = (node) => node.isKind(tsm.SyntaxKind.TypeOperator) && node.getOperator() === tsm.SyntaxKind.ReadonlyKeyword && node.getTypeNode().isKind(tsm.SyntaxKind.TupleType);
18
10
  const isReadonlyTypeReferenceNode = (node) => {
19
- if (!node.isKind(tsm.SyntaxKind.TypeReference)) {
20
- return false;
21
- }
22
- const typeName = node.getTypeName();
23
- const typeArguments = node.getTypeArguments();
24
- return (typeName.isKind(tsm.SyntaxKind.Identifier) &&
25
- typeName.getText() === 'Readonly' &&
26
- Arr.isArrayOfLength(typeArguments, 1));
11
+ if (!node.isKind(tsm.SyntaxKind.TypeReference)) {
12
+ return false;
13
+ }
14
+ const typeName = node.getTypeName();
15
+ const typeArguments = node.getTypeArguments();
16
+ return typeName.isKind(tsm.SyntaxKind.Identifier) && typeName.getText() === "Readonly" && Arr.isArrayOfLength(typeArguments, 1);
27
17
  };
28
18
 
29
19
  export { isReadonlyArrayTypeNode, isReadonlyTupleOrArrayTypeNode, isReadonlyTupleTypeNode, isReadonlyTypeReferenceNode, isShallowReadonlyTypeNode };
@@ -1 +1 @@
1
- {"version":3,"file":"is-readonly-node.mjs","sources":["../../../src/functions/functions/is-readonly-node.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;AAKO,MAAM,yBAAyB,GAAG,CAAC,IAAc,KACtD,8BAA8B,CAAC,IAAI,CAAC;IACpC,2BAA2B,CAAC,IAAI,CAAC;IACjC,gBAAgB,CAAC,IAAI;AAEhB,MAAM,8BAA8B,GAAG,CAC5C,IAA4B,KAE5B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC;IACxC,IAAI,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,UAAU,CAAC,eAAe;AACrD,KAAC,IAAI,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC;AAClD,QAAA,IAAI,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC;AAShD,MAAM,uBAAuB,GAAG,CACrC,IAA4B,KAE5B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC;IACxC,IAAI,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,UAAU,CAAC,eAAe;AACrD,IAAA,IAAI,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS;AAqE7C,MAAM,uBAAuB,GAAG,CACrC,IAA4B,KAE5B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC;IACxC,IAAI,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,UAAU,CAAC,eAAe;AACrD,IAAA,IAAI,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS;AA4D7C,MAAM,2BAA2B,GAAG,CACzC,IAA4B,KACS;AACrC,IAAA,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE;AAC9C,QAAA,OAAO,KAAK;;AAGd,IAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE;AAEnC,IAAA,MAAM,aAAa,GAAG,IAAI,CAAC,gBAAgB,EAAE;IAE7C,QACE,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC;AAC1C,QAAA,QAAQ,CAAC,OAAO,EAAE,KAAK,UAAU;QACjC,GAAG,CAAC,eAAe,CAAC,aAAa,EAAE,CAAC,CAAC;AAEzC;;;;"}
1
+ {"version":3,"file":"is-readonly-node.mjs","sources":["../../../src/functions/functions/is-readonly-node.mts"],"sourcesContent":["import { Arr, expectType } from 'ts-data-forge';\nimport * as tsm from 'ts-morph';\nimport { type DeepReadonly } from 'ts-type-forge';\nimport { isAtomicTypeNode } from './is-atomic-type-node.mjs';\n\nexport const isShallowReadonlyTypeNode = (node: tsm.Node): boolean =>\n isReadonlyTupleOrArrayTypeNode(node) ||\n isReadonlyTypeReferenceNode(node) ||\n isAtomicTypeNode(node);\n\nexport const isReadonlyTupleOrArrayTypeNode = (\n node: DeepReadonly<tsm.Node>,\n): node is ReadonlyArrayTypeNode | ReadonlyTupleTypeNode =>\n node.isKind(tsm.SyntaxKind.TypeOperator) &&\n node.getOperator() === tsm.SyntaxKind.ReadonlyKeyword &&\n (node.getTypeNode().isKind(tsm.SyntaxKind.ArrayType) || // Use optional chaining and isKind\n node.getTypeNode().isKind(tsm.SyntaxKind.TupleType));\n\nexport type ReadonlyArrayTypeNode = tsm.TypeNode &\n Omit<tsm.TypeOperatorTypeNode, 'getOperator' | 'getTypeNode'> &\n Readonly<{\n getOperator: () => tsm.SyntaxKind.ReadonlyKeyword;\n getTypeNode: () => tsm.ArrayTypeNode;\n }>;\n\nexport const isReadonlyArrayTypeNode = (\n node: DeepReadonly<tsm.Node>,\n): node is ReadonlyArrayTypeNode =>\n node.isKind(tsm.SyntaxKind.TypeOperator) &&\n node.getOperator() === tsm.SyntaxKind.ReadonlyKeyword &&\n node.getTypeNode().isKind(tsm.SyntaxKind.ArrayType);\n\n// Helper to get a specific type node from source code\nconst getTypeNodeFromSource = (\n sourceCode: string,\n typeName: string,\n): tsm.Node => {\n const project = new tsm.Project({ useInMemoryFileSystem: true });\n\n const sourceFile = project.createSourceFile('test.ts', sourceCode);\n\n const typeAlias = sourceFile.getTypeAliasOrThrow(typeName);\n\n return typeAlias.getTypeNodeOrThrow();\n};\n\nif (import.meta.vitest !== undefined) {\n describe('isReadonlyArrayTypeNode', () => {\n test('should return true for readonly array type', () => {\n const node = getTypeNodeFromSource(\n 'type Test = readonly number[];',\n 'Test',\n );\n\n if (isReadonlyArrayTypeNode(node)) {\n const _operator = node.getOperator();\n\n expectType<typeof _operator, tsm.SyntaxKind.ReadonlyKeyword>('=');\n\n const _typeNode = node.getTypeNode();\n\n expectType<typeof _typeNode, tsm.ArrayTypeNode>('=');\n }\n\n assert.isTrue(node.isKind(tsm.SyntaxKind.TypeOperator));\n\n if (!isReadonlyArrayTypeNode(node)) {\n throw new Error('node should be ReadonlyArrayTypeNode');\n }\n\n expect(node.getOperator()).toBe(tsm.SyntaxKind.ReadonlyKeyword);\n\n assert.isTrue(node.getTypeNode().isKind(tsm.SyntaxKind.ArrayType));\n });\n\n test('should return false for non-readonly array', () => {\n const node = getTypeNodeFromSource('type Test = string[];', 'Test');\n\n assert.isFalse(isReadonlyArrayTypeNode(node));\n });\n\n test('should return false for readonly tuple', () => {\n const node = getTypeNodeFromSource(\n 'type Test = readonly [string];',\n 'Test',\n );\n\n assert.isFalse(isReadonlyArrayTypeNode(node));\n });\n });\n}\n\nexport type ReadonlyTupleTypeNode = tsm.TypeNode &\n Omit<tsm.TypeOperatorTypeNode, 'getOperator' | 'getTypeNode'> &\n Readonly<{\n getOperator: () => tsm.SyntaxKind.ReadonlyKeyword;\n getTypeNode: () => tsm.TupleTypeNode;\n }>;\n\nexport const isReadonlyTupleTypeNode = (\n node: DeepReadonly<tsm.Node>,\n): node is ReadonlyTupleTypeNode =>\n node.isKind(tsm.SyntaxKind.TypeOperator) &&\n node.getOperator() === tsm.SyntaxKind.ReadonlyKeyword &&\n node.getTypeNode().isKind(tsm.SyntaxKind.TupleType);\n\nif (import.meta.vitest !== undefined) {\n describe('isReadonlyTupleTypeNode', () => {\n test('should return true for readonly tuple type', () => {\n const node = getTypeNodeFromSource(\n 'type Test = readonly [number, string];',\n 'Test',\n );\n\n assert.isTrue(isReadonlyTupleTypeNode(node));\n\n if (isReadonlyTupleTypeNode(node)) {\n const _operator = node.getOperator();\n\n expectType<typeof _operator, tsm.SyntaxKind.ReadonlyKeyword>('=');\n\n const _typeNode = node.getTypeNode();\n\n expectType<typeof _typeNode, tsm.TupleTypeNode>('=');\n }\n\n assert.isTrue(node.isKind(tsm.SyntaxKind.TypeOperator));\n\n if (!isReadonlyTupleTypeNode(node)) {\n throw new Error('node should be ReadonlyTupleTypeNode');\n }\n\n expect(node.getOperator()).toBe(tsm.SyntaxKind.ReadonlyKeyword);\n\n assert.isTrue(node.getTypeNode().isKind(tsm.SyntaxKind.TupleType));\n });\n\n test('should return false for non-readonly tuple', () => {\n const node = getTypeNodeFromSource('type Test = [boolean];', 'Test');\n\n assert.isFalse(isReadonlyTupleTypeNode(node));\n });\n\n test('should return false for readonly array', () => {\n const node = getTypeNodeFromSource(\n 'type Test = readonly number[];',\n 'Test',\n );\n\n assert.isFalse(isReadonlyTupleTypeNode(node));\n });\n });\n}\n\nexport type ReadonlyTypeReferenceNode = tsm.TypeNode &\n Omit<tsm.TypeReferenceNode, 'getTypeName' | 'getTypeArguments'> &\n Readonly<{\n getTypeName: () => Omit<tsm.Identifier, 'getText'> &\n Readonly<{\n getText: () => 'Readonly';\n }>;\n getTypeArguments: () => readonly [tsm.TypeNode];\n }>;\n\nexport const isReadonlyTypeReferenceNode = (\n node: DeepReadonly<tsm.Node>,\n): node is ReadonlyTypeReferenceNode => {\n if (!node.isKind(tsm.SyntaxKind.TypeReference)) {\n return false;\n }\n\n const typeName = node.getTypeName();\n\n const typeArguments = node.getTypeArguments();\n\n return (\n typeName.isKind(tsm.SyntaxKind.Identifier) &&\n typeName.getText() === 'Readonly' &&\n Arr.isArrayOfLength(typeArguments, 1)\n );\n};\n\nif (import.meta.vitest !== undefined) {\n describe('isReadonlyTypeReferenceNode', () => {\n test('should return true for Readonly<T>', () => {\n const node = getTypeNodeFromSource(\n 'type Test = Readonly<{ x: number }>;',\n 'Test',\n );\n\n assert.isTrue(isReadonlyTypeReferenceNode(node));\n\n if (isReadonlyTypeReferenceNode(node)) {\n const _typeNameText = node.getTypeName().getText();\n\n expectType<typeof _typeNameText, 'Readonly'>('=');\n\n const _typeArguments = node.getTypeArguments();\n\n expectType<\n typeof _typeArguments,\n readonly [tsm.TypeNode<tsm.ts.TypeNode>]\n >('=');\n }\n\n assert.isTrue(node.isKind(tsm.SyntaxKind.TypeReference));\n\n if (!isReadonlyTypeReferenceNode(node)) {\n throw new Error('node should be ReadonlyNode');\n }\n\n expect(node.getTypeName().getText()).toBe('Readonly');\n\n expect(node.getTypeArguments()).toHaveLength(1);\n });\n\n test('should return false for other type references', () => {\n const node = getTypeNodeFromSource(\n 'type Test = Partial<{ y: string }>;',\n 'Test',\n );\n\n assert.isFalse(isReadonlyTypeReferenceNode(node));\n });\n\n test('should return false for Readonly without type arguments', () => {\n // Note: This is syntactically incorrect TS, but testing the guard\n const node = getTypeNodeFromSource('type Test = Readonly;', 'Test');\n\n assert.isFalse(isReadonlyTypeReferenceNode(node));\n });\n\n test('should return false for Readonly with multiple type arguments', () => {\n // Note: This is syntactically incorrect TS, but testing the guard\n const project = new tsm.Project({ useInMemoryFileSystem: true });\n\n // Need to create manually as TS parser might reject Readonly<A, B>\n const sourceFile = project.createSourceFile(\n 'test.ts',\n 'type Test = Readonly<string, number>;',\n );\n\n const node = sourceFile.getTypeAliasOrThrow('Test').getTypeNodeOrThrow();\n\n assert.isFalse(isReadonlyTypeReferenceNode(node));\n });\n });\n}\n"],"names":[],"mappings":";;;;MAKa,yBAAA,GAA4B,CAAC,IAAA,KACxC,8BAAA,CAA+B,IAAI,KACnC,2BAAA,CAA4B,IAAI,CAAA,IAChC,gBAAA,CAAiB,IAAI;MAEV,8BAAA,GAAiC,CAC5C,IAAA,KAEA,IAAA,CAAK,OAAO,GAAA,CAAI,UAAA,CAAW,YAAY,CAAA,IACvC,IAAA,CAAK,aAAY,KAAM,GAAA,CAAI,WAAW,eAAA,KACrC,IAAA,CAAK,aAAY,CAAE,MAAA,CAAO,GAAA,CAAI,UAAA,CAAW,SAAS,CAAA;AACjD,IAAA,CAAK,WAAA,EAAY,CAAE,MAAA,CAAO,GAAA,CAAI,WAAW,SAAS,CAAA;MASzC,uBAAA,GAA0B,CACrC,IAAA,KAEA,IAAA,CAAK,OAAO,GAAA,CAAI,UAAA,CAAW,YAAY,CAAA,IACvC,IAAA,CAAK,aAAY,KAAM,GAAA,CAAI,WAAW,eAAA,IACtC,IAAA,CAAK,aAAY,CAAE,MAAA,CAAO,GAAA,CAAI,UAAA,CAAW,SAAS;MAqEvC,uBAAA,GAA0B,CACrC,IAAA,KAEA,IAAA,CAAK,OAAO,GAAA,CAAI,UAAA,CAAW,YAAY,CAAA,IACvC,IAAA,CAAK,aAAY,KAAM,GAAA,CAAI,WAAW,eAAA,IACtC,IAAA,CAAK,aAAY,CAAE,MAAA,CAAO,GAAA,CAAI,UAAA,CAAW,SAAS;AA4D7C,MAAM,2BAAA,GAA8B,CACzC,IAAA,KACsC;AACtC,EAAA,IAAI,CAAC,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,UAAA,CAAW,aAAa,CAAA,EAAG;AAC9C,IAAA,OAAO,KAAA;AAAA,EAAA;AAGT,EAAA,MAAM,QAAA,GAAW,KAAK,WAAA,EAAY;AAElC,EAAA,MAAM,aAAA,GAAgB,KAAK,gBAAA,EAAiB;AAE5C,EAAA,OACE,QAAA,CAAS,MAAA,CAAO,GAAA,CAAI,UAAA,CAAW,UAAU,CAAA,IACzC,QAAA,CAAS,OAAA,EAAQ,KAAM,UAAA,IACvB,GAAA,CAAI,eAAA,CAAgB,eAAe,CAAC,CAAA;AAExC;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"is-spread-parameter-node.d.mts","sourceRoot":"","sources":["../../../src/functions/functions/is-spread-parameter-node.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAEhC,eAAO,MAAM,qBAAqB,GAChC,MAAM,GAAG,CAAC,IAAI,KACb,IAAI,IAAI,GAAG,CAAC,oBAEyB,CAAC;AAEzC,eAAO,MAAM,4BAA4B,GACvC,MAAM,GAAG,CAAC,IAAI,KACb,IAAI,IAAI,GAAG,CAAC,gBAEyB,CAAC"}
1
+ {"version":3,"file":"is-spread-parameter-node.d.mts","sourceRoot":"","sources":["../../../src/functions/functions/is-spread-parameter-node.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAEhC,eAAO,MAAM,qBAAqB,SAC1B,GAAG,CAAC,IAAI,KACb,IAAI,IAAI,GAAG,CAAC,oBAEyB,CAAC;AAEzC,eAAO,MAAM,4BAA4B,SACjC,GAAG,CAAC,IAAI,KACb,IAAI,IAAI,GAAG,CAAC,gBAEyB,CAAC"}
@@ -1,9 +1,7 @@
1
1
  import * as tsm from 'ts-morph';
2
2
 
3
- const isSpreadParameterNode = (node) => node.isKind(tsm.SyntaxKind.Parameter) &&
4
- node.getDotDotDotToken() !== undefined;
5
- const isSpreadNamedTupleMemberNode = (node) => node.isKind(tsm.SyntaxKind.NamedTupleMember) &&
6
- node.getDotDotDotToken() !== undefined;
3
+ const isSpreadParameterNode = (node) => node.isKind(tsm.SyntaxKind.Parameter) && node.getDotDotDotToken() !== void 0;
4
+ const isSpreadNamedTupleMemberNode = (node) => node.isKind(tsm.SyntaxKind.NamedTupleMember) && node.getDotDotDotToken() !== void 0;
7
5
 
8
6
  export { isSpreadNamedTupleMemberNode, isSpreadParameterNode };
9
7
  //# sourceMappingURL=is-spread-parameter-node.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"is-spread-parameter-node.mjs","sources":["../../../src/functions/functions/is-spread-parameter-node.mts"],"sourcesContent":[null],"names":[],"mappings":";;AAEO,MAAM,qBAAqB,GAAG,CACnC,IAAc,KAEd,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC;AACrC,IAAA,IAAI,CAAC,iBAAiB,EAAE,KAAK;AAExB,MAAM,4BAA4B,GAAG,CAC1C,IAAc,KAEd,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,gBAAgB,CAAC;AAC5C,IAAA,IAAI,CAAC,iBAAiB,EAAE,KAAK;;;;"}
1
+ {"version":3,"file":"is-spread-parameter-node.mjs","sources":["../../../src/functions/functions/is-spread-parameter-node.mts"],"sourcesContent":["import * as tsm from 'ts-morph';\n\nexport const isSpreadParameterNode = (\n node: tsm.Node,\n): node is tsm.ParameterDeclaration =>\n node.isKind(tsm.SyntaxKind.Parameter) &&\n node.getDotDotDotToken() !== undefined;\n\nexport const isSpreadNamedTupleMemberNode = (\n node: tsm.Node,\n): node is tsm.NamedTupleMember =>\n node.isKind(tsm.SyntaxKind.NamedTupleMember) &&\n node.getDotDotDotToken() !== undefined;\n"],"names":[],"mappings":";;AAEO,MAAM,qBAAA,GAAwB,CACnC,IAAA,KAEA,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,UAAA,CAAW,SAAS,CAAA,IACpC,IAAA,CAAK,iBAAA,EAAkB,KAAM;AAExB,MAAM,4BAAA,GAA+B,CAC1C,IAAA,KAEA,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,UAAA,CAAW,gBAAgB,CAAA,IAC3C,IAAA,CAAK,iBAAA,EAAkB,KAAM;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"remove-parentheses.d.mts","sourceRoot":"","sources":["../../../src/functions/functions/remove-parentheses.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAGhC,eAAO,MAAM,iBAAiB,GAAI,MAAM,GAAG,CAAC,QAAQ,KAAG,GAAG,CAAC,QAGjD,CAAC"}
1
+ {"version":3,"file":"remove-parentheses.d.mts","sourceRoot":"","sources":["../../../src/functions/functions/remove-parentheses.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAGhC,eAAO,MAAM,iBAAiB,SAAU,GAAG,CAAC,QAAQ,KAAG,GAAG,CAAC,QAGjD,CAAC"}
@@ -1,9 +1,6 @@
1
1
  import * as tsm from 'ts-morph';
2
2
 
3
- // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
4
- const removeParentheses = (node) => node.isKind(tsm.SyntaxKind.ParenthesizedType)
5
- ? removeParentheses(node.getTypeNode())
6
- : node;
3
+ const removeParentheses = (node) => node.isKind(tsm.SyntaxKind.ParenthesizedType) ? removeParentheses(node.getTypeNode()) : node;
7
4
 
8
5
  export { removeParentheses };
9
6
  //# sourceMappingURL=remove-parentheses.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"remove-parentheses.mjs","sources":["../../../src/functions/functions/remove-parentheses.mts"],"sourcesContent":[null],"names":[],"mappings":";;AAEA;AACO,MAAM,iBAAiB,GAAG,CAAC,IAAkB,KAClD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,iBAAiB;AAC1C,MAAE,iBAAiB,CAAC,IAAI,CAAC,WAAW,EAAE;MACpC;;;;"}
1
+ {"version":3,"file":"remove-parentheses.mjs","sources":["../../../src/functions/functions/remove-parentheses.mts"],"sourcesContent":["import * as tsm from 'ts-morph';\n\n// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types\nexport const removeParentheses = (node: tsm.TypeNode): tsm.TypeNode =>\n node.isKind(tsm.SyntaxKind.ParenthesizedType)\n ? removeParentheses(node.getTypeNode())\n : node;\n"],"names":[],"mappings":";;AAGO,MAAM,iBAAA,GAAoB,CAAC,IAAA,KAChC,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,UAAA,CAAW,iBAAiB,CAAA,GACxC,iBAAA,CAAkB,IAAA,CAAK,WAAA,EAAa,CAAA,GACpC;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"should-avoid-parentheses-for-readonly.d.mts","sourceRoot":"","sources":["../../../src/functions/functions/should-avoid-parentheses-for-readonly.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAEhC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,iCAAiC,GAAI,MAAM,GAAG,CAAC,IAAI,KAAG,OAgBlE,CAAC"}
1
+ {"version":3,"file":"should-avoid-parentheses-for-readonly.d.mts","sourceRoot":"","sources":["../../../src/functions/functions/should-avoid-parentheses-for-readonly.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAEhC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,iCAAiC,SAAU,GAAG,CAAC,IAAI,KAAG,OAgBlE,CAAC"}
@@ -1,31 +1,14 @@
1
1
  import * as tsm from 'ts-morph';
2
2
 
3
- /**
4
- * Determines if parentheses should be avoided when adding 'readonly' prefix to a type.
5
- *
6
- * Parentheses should be AVOIDED in these specific contexts:
7
- * - Type predicates: `x is [T, U]` -> `x is readonly [T, U]` (not `x is (readonly [T, U])`)
8
- * because parentheses around the type in a type predicate cause syntax errors
9
- *
10
- * For all other contexts, we keep parentheses for safety to avoid precedence issues,
11
- * relying on prettier to remove unnecessary ones.
12
- *
13
- * @param node - The type node to check
14
- * @returns true if parentheses should be avoided, false otherwise (keep parentheses)
15
- */
16
3
  const shouldAvoidParenthesesForReadonly = (node) => {
17
- const parent = node.getParent();
18
- if (parent === undefined) {
19
- return false;
20
- }
21
- // Check if parent is TypePredicate: x is T
22
- // In this case, we MUST avoid parentheses: x is readonly T (not x is (readonly T))
23
- // because `x is (readonly T)` is a syntax error
24
- if (parent.isKind(tsm.SyntaxKind.TypePredicate)) {
25
- return true;
26
- }
27
- // For all other cases, keep parentheses for safety
4
+ const parent = node.getParent();
5
+ if (parent === void 0) {
28
6
  return false;
7
+ }
8
+ if (parent.isKind(tsm.SyntaxKind.TypePredicate)) {
9
+ return true;
10
+ }
11
+ return false;
29
12
  };
30
13
 
31
14
  export { shouldAvoidParenthesesForReadonly };
@@ -1 +1 @@
1
- {"version":3,"file":"should-avoid-parentheses-for-readonly.mjs","sources":["../../../src/functions/functions/should-avoid-parentheses-for-readonly.mts"],"sourcesContent":[null],"names":[],"mappings":";;AAEA;;;;;;;;;;;;AAYG;AACI,MAAM,iCAAiC,GAAG,CAAC,IAAc,KAAa;AAC3E,IAAA,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE;AAE/B,IAAA,IAAI,MAAM,KAAK,SAAS,EAAE;AACxB,QAAA,OAAO,KAAK;IACd;;;;IAKA,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE;AAC/C,QAAA,OAAO,IAAI;IACb;;AAGA,IAAA,OAAO,KAAK;AACd;;;;"}
1
+ {"version":3,"file":"should-avoid-parentheses-for-readonly.mjs","sources":["../../../src/functions/functions/should-avoid-parentheses-for-readonly.mts"],"sourcesContent":["import * as tsm from 'ts-morph';\n\n/**\n * Determines if parentheses should be avoided when adding 'readonly' prefix to a type.\n *\n * Parentheses should be AVOIDED in these specific contexts:\n * - Type predicates: `x is [T, U]` -> `x is readonly [T, U]` (not `x is (readonly [T, U])`)\n * because parentheses around the type in a type predicate cause syntax errors\n *\n * For all other contexts, we keep parentheses for safety to avoid precedence issues,\n * relying on prettier to remove unnecessary ones.\n *\n * @param node - The type node to check\n * @returns true if parentheses should be avoided, false otherwise (keep parentheses)\n */\nexport const shouldAvoidParenthesesForReadonly = (node: tsm.Node): boolean => {\n const parent = node.getParent();\n\n if (parent === undefined) {\n return false;\n }\n\n // Check if parent is TypePredicate: x is T\n // In this case, we MUST avoid parentheses: x is readonly T (not x is (readonly T))\n // because `x is (readonly T)` is a syntax error\n if (parent.isKind(tsm.SyntaxKind.TypePredicate)) {\n return true;\n }\n\n // For all other cases, keep parentheses for safety\n return false;\n};\n"],"names":[],"mappings":";;AAeO,MAAM,iCAAA,GAAoC,CAAC,IAAA,KAA4B;AAC5E,EAAA,MAAM,MAAA,GAAS,KAAK,SAAA,EAAU;AAE9B,EAAA,IAAI,WAAW,MAAA,EAAW;AACxB,IAAA,OAAO,KAAA;AAAA,EACT;AAKA,EAAA,IAAI,MAAA,CAAO,MAAA,CAAO,GAAA,CAAI,UAAA,CAAW,aAAa,CAAA,EAAG;AAC/C,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,OAAO,KAAA;AACT;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"unwrap-readonly.d.mts","sourceRoot":"","sources":["../../../src/functions/functions/unwrap-readonly.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAGxE,eAAO,MAAM,yBAAyB,GAEpC,MAAM,yBAAyB,KAC9B,MAAuE,CAAC"}
1
+ {"version":3,"file":"unwrap-readonly.d.mts","sourceRoot":"","sources":["../../../src/functions/functions/unwrap-readonly.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAGxE,eAAO,MAAM,yBAAyB,SAE9B,yBAAyB,KAC9B,MAAuE,CAAC"}
@@ -1,8 +1,6 @@
1
1
  import { wrapWithParentheses } from './wrap-with-parentheses.mjs';
2
2
 
3
- const unwrapReadonlyTypeArgText = (
4
- // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
5
- node) => wrapWithParentheses(node.getTypeArguments()[0].getFullText());
3
+ const unwrapReadonlyTypeArgText = (node) => wrapWithParentheses(node.getTypeArguments()[0].getFullText());
6
4
 
7
5
  export { unwrapReadonlyTypeArgText };
8
6
  //# sourceMappingURL=unwrap-readonly.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"unwrap-readonly.mjs","sources":["../../../src/functions/functions/unwrap-readonly.mts"],"sourcesContent":[null],"names":[],"mappings":";;AAGO,MAAM,yBAAyB,GAAG;AACvC;AACA,IAA+B,KACpB,mBAAmB,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;;;;"}
1
+ {"version":3,"file":"unwrap-readonly.mjs","sources":["../../../src/functions/functions/unwrap-readonly.mts"],"sourcesContent":["import { type ReadonlyTypeReferenceNode } from './is-readonly-node.mjs';\nimport { wrapWithParentheses } from './wrap-with-parentheses.mjs';\n\nexport const unwrapReadonlyTypeArgText = (\n // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types\n node: ReadonlyTypeReferenceNode,\n): string => wrapWithParentheses(node.getTypeArguments()[0].getFullText());\n"],"names":[],"mappings":";;AAGO,MAAM,yBAAA,GAA4B,CAEvC,IAAA,KACW,mBAAA,CAAoB,IAAA,CAAK,kBAAiB,CAAE,CAAC,CAAA,CAAE,WAAA,EAAa;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"wrap-with-parentheses.d.mts","sourceRoot":"","sources":["../../../src/functions/functions/wrap-with-parentheses.mts"],"names":[],"mappings":"AAsDA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,GAAI,SAAS,MAAM,KAAG,MAQrD,CAAC"}
1
+ {"version":3,"file":"wrap-with-parentheses.d.mts","sourceRoot":"","sources":["../../../src/functions/functions/wrap-with-parentheses.mts"],"names":[],"mappings":"AAgDA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,YAAa,MAAM,KAAG,MAQrD,CAAC"}
@@ -1,60 +1,35 @@
1
1
  import { range, asUint32 } from 'ts-data-forge';
2
2
 
3
- /**
4
- * Checks if a string is already wrapped with a single pair of balanced parentheses
5
- * that encompasses the entire expression.
6
- *
7
- * @example
8
- * isWrappedWithParentheses('(A)') // true
9
- * isWrappedWithParentheses('((A))') // true (outer pair wraps everything)
10
- * isWrappedWithParentheses('(A) | (B)') // false (outer parens don't wrap everything)
11
- * isWrappedWithParentheses('A') // false
12
- */
3
+ const parenDepthDelta = (char) => {
4
+ switch (char) {
5
+ case "(":
6
+ return 1;
7
+ case ")":
8
+ return -1;
9
+ default:
10
+ return 0;
11
+ }
12
+ };
13
13
  const isWrappedWithParentheses = (str) => {
14
- const trimmed = str.trim();
15
- if (!trimmed.startsWith('(') || !trimmed.endsWith(')')) {
16
- return false;
17
- }
18
- // Check if the opening and closing parentheses are balanced
19
- // and the opening parenthesis corresponds to the closing one
20
- let mut_depth = 0;
21
- for (const mut_i of range(0, asUint32(trimmed.length))) {
22
- const char = trimmed.charAt(mut_i);
23
- switch (char) {
24
- case '(': {
25
- mut_depth += 1;
26
- break;
27
- }
28
- case ')': {
29
- mut_depth -= 1;
30
- // If we reach depth 0 before the end, the outer parentheses don't wrap everything
31
- if (mut_depth === 0 && mut_i < trimmed.length - 1) {
32
- return false;
33
- }
34
- break;
35
- }
36
- }
14
+ const trimmed = str.trim();
15
+ if (!trimmed.startsWith("(") || !trimmed.endsWith(")")) {
16
+ return false;
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;
37
23
  }
38
- return true;
24
+ }
25
+ return true;
39
26
  };
40
- /**
41
- * Wraps a string with parentheses if not already wrapped.
42
- * Avoids adding redundant parentheses when the expression is already
43
- * fully wrapped with balanced parentheses.
44
- *
45
- * @example
46
- * wrapWithParentheses('A') // '(A)'
47
- * wrapWithParentheses('(A)') // '(A)' (not '((A))')
48
- * wrapWithParentheses('A | B') // '(A | B)'
49
- * wrapWithParentheses('(A | B)') // '(A | B)' (not '((A | B))')
50
- * wrapWithParentheses('(A) | (B)') // '((A) | (B))' (needs outer parens)
51
- */
52
27
  const wrapWithParentheses = (nodeStr) => {
53
- const trimmed = nodeStr.trim();
54
- if (isWrappedWithParentheses(trimmed)) {
55
- return trimmed;
56
- }
57
- return `(${trimmed})`;
28
+ const trimmed = nodeStr.trim();
29
+ if (isWrappedWithParentheses(trimmed)) {
30
+ return trimmed;
31
+ }
32
+ return `(${trimmed})`;
58
33
  };
59
34
 
60
35
  export { wrapWithParentheses };
@@ -1 +1 @@
1
- {"version":3,"file":"wrap-with-parentheses.mjs","sources":["../../../src/functions/functions/wrap-with-parentheses.mts"],"sourcesContent":[null],"names":[],"mappings":";;AAAA;;;;;;;;;AASG;AAGH,MAAM,wBAAwB,GAAG,CAAC,GAAW,KAAa;AACxD,IAAA,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE;AAE1B,IAAA,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;AACtD,QAAA,OAAO,KAAK;IACd;;;IAIA,IAAI,SAAS,GAAG,CAAC;AAEjB,IAAA,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE;QACtD,MAAM,IAAI,GAAW,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;QAE1C,QAAQ,IAAI;YACV,KAAK,GAAG,EAAE;gBACR,SAAS,IAAI,CAAC;gBAEd;YACF;YAEA,KAAK,GAAG,EAAE;gBACR,SAAS,IAAI,CAAC;;AAGd,gBAAA,IAAI,SAAS,KAAK,CAAC,IAAI,KAAK,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE;AACjD,oBAAA,OAAO,KAAK;gBACd;gBAEA;YACF;;IAOJ;AAEA,IAAA,OAAO,IAAI;AACb,CAAC;AAED;;;;;;;;;;;AAWG;AACI,MAAM,mBAAmB,GAAG,CAAC,OAAe,KAAY;AAC7D,IAAA,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE;AAE9B,IAAA,IAAI,wBAAwB,CAAC,OAAO,CAAC,EAAE;AACrC,QAAA,OAAO,OAAO;IAChB;IAEA,OAAO,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA,CAAY;AAChC;;;;"}
1
+ {"version":3,"file":"wrap-with-parentheses.mjs","sources":["../../../src/functions/functions/wrap-with-parentheses.mts"],"sourcesContent":["/**\n * Checks if a string is already wrapped with a single pair of balanced parentheses\n * that encompasses the entire expression.\n *\n * @example\n * isWrappedWithParentheses('(A)') // true\n * isWrappedWithParentheses('((A))') // true (outer pair wraps everything)\n * isWrappedWithParentheses('(A) | (B)') // false (outer parens don't wrap everything)\n * isWrappedWithParentheses('A') // false\n */\nimport { asUint32, range } from 'ts-data-forge';\n\nconst parenDepthDelta = (char: string): number => {\n switch (char) {\n case '(':\n return 1;\n\n case ')':\n return -1;\n\n default:\n return 0;\n }\n};\n\nconst isWrappedWithParentheses = (str: string): boolean => {\n const trimmed = str.trim();\n\n if (!trimmed.startsWith('(') || !trimmed.endsWith(')')) {\n return false;\n }\n\n // Check if the opening and closing parentheses are balanced\n // and the opening parenthesis corresponds to the closing one\n let mut_depth = 0;\n\n for (const mut_i of range(0, asUint32(trimmed.length))) {\n mut_depth += parenDepthDelta(trimmed.charAt(mut_i));\n\n // If we reach depth 0 before the end, the outer parentheses don't wrap everything\n if (mut_depth === 0 && mut_i < trimmed.length - 1) {\n return false;\n }\n }\n\n return true;\n};\n\n/**\n * Wraps a string with parentheses if not already wrapped.\n * Avoids adding redundant parentheses when the expression is already\n * fully wrapped with balanced parentheses.\n *\n * @example\n * wrapWithParentheses('A') // '(A)'\n * wrapWithParentheses('(A)') // '(A)' (not '((A))')\n * wrapWithParentheses('A | B') // '(A | B)'\n * wrapWithParentheses('(A | B)') // '(A | B)' (not '((A | B))')\n * wrapWithParentheses('(A) | (B)') // '((A) | (B))' (needs outer parens)\n */\nexport const wrapWithParentheses = (nodeStr: string): string => {\n const trimmed = nodeStr.trim();\n\n if (isWrappedWithParentheses(trimmed)) {\n return trimmed;\n }\n\n return `(${trimmed})` as const;\n};\n"],"names":[],"mappings":";;AAYA,MAAM,eAAA,GAAkB,CAAC,IAAA,KAAyB;AAChD,EAAA,QAAQ,IAAA;AAAM,IACZ,KAAK,GAAA;AACH,MAAA,OAAO,CAAA;AAAA,IAET,KAAK,GAAA;AACH,MAAA,OAAO,EAAA;AAAA,IAET;AACE,MAAA,OAAO,CAAA;AAAA;AAEb,CAAA;AAEA,MAAM,wBAAA,GAA2B,CAAC,GAAA,KAAyB;AACzD,EAAA,MAAM,OAAA,GAAU,IAAI,IAAA,EAAK;AAEzB,EAAA,IAAI,CAAC,QAAQ,UAAA,CAAW,GAAG,KAAK,CAAC,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,EAAG;AACtD,IAAA,OAAO,KAAA;AAAA,EACT;AAIA,EAAA,IAAI,SAAA,GAAY,CAAA;AAEhB,EAAA,KAAA,MAAW,SAAS,KAAA,CAAM,CAAA,EAAG,SAAS,OAAA,CAAQ,MAAM,CAAC,CAAA,EAAG;AACtD,IAAA,SAAA,IAAa,eAAA,CAAgB,OAAA,CAAQ,MAAA,CAAO,KAAK,CAAC,CAAA;AAGlD,IAAA,IAAI,SAAA,KAAc,CAAA,IAAK,KAAA,GAAQ,OAAA,CAAQ,SAAS,CAAA,EAAG;AACjD,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,OAAO,IAAA;AACT,CAAA;AAcO,MAAM,mBAAA,GAAsB,CAAC,OAAA,KAA4B;AAC9D,EAAA,MAAM,OAAA,GAAU,QAAQ,IAAA,EAAK;AAE7B,EAAA,IAAI,wBAAA,CAAyB,OAAO,CAAA,EAAG;AACrC,IAAA,OAAO,OAAA;AAAA,EACT;AAEA,EAAA,OAAO,IAAI,OAAO,CAAA,CAAA,CAAA;AACpB;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"replace-with-debug.d.mts","sourceRoot":"","sources":["../../../src/functions/utils/replace-with-debug.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,GAAG,MAAM,UAAU,CAAC;AAErC,eAAO,MAAM,yBAAyB,GACpC,MAAM,GAAG,CAAC,IAAI,EACd,aAAa,MAAM,KAClB,IAIF,CAAC"}
1
+ {"version":3,"file":"replace-with-debug.d.mts","sourceRoot":"","sources":["../../../src/functions/utils/replace-with-debug.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,GAAG,MAAM,UAAU,CAAC;AAErC,eAAO,MAAM,yBAAyB,SAC9B,GAAG,CAAC,IAAI,eACD,MAAM,KAClB,IAIF,CAAC"}
@@ -1,6 +1,6 @@
1
1
  const replaceNodeWithDebugPrint = (node, newNodeText) => {
2
- console.debug(`${node.getText()} -> ${newNodeText}`);
3
- node.replaceWithText(newNodeText);
2
+ console.debug(`${node.getText()} -> ${newNodeText}`);
3
+ node.replaceWithText(newNodeText);
4
4
  };
5
5
 
6
6
  export { replaceNodeWithDebugPrint };
@@ -1 +1 @@
1
- {"version":3,"file":"replace-with-debug.mjs","sources":["../../../src/functions/utils/replace-with-debug.mts"],"sourcesContent":[null],"names":[],"mappings":"MAEa,yBAAyB,GAAG,CACvC,IAAc,EACd,WAAmB,KACX;AACR,IAAA,OAAO,CAAC,KAAK,CAAC,CAAA,EAAG,IAAI,CAAC,OAAO,EAAE,CAAA,IAAA,EAAO,WAAW,CAAA,CAAE,CAAC;AAEpD,IAAA,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC;AACnC;;;;"}
1
+ {"version":3,"file":"replace-with-debug.mjs","sources":["../../../src/functions/utils/replace-with-debug.mts"],"sourcesContent":["import type * as tsm from 'ts-morph';\n\nexport const replaceNodeWithDebugPrint = (\n node: tsm.Node,\n newNodeText: string,\n): void => {\n console.debug(`${node.getText()} -> ${newNodeText}`);\n\n node.replaceWithText(newNodeText);\n};\n"],"names":[],"mappings":"AAEO,MAAM,yBAAA,GAA4B,CACvC,IAAA,EACA,WAAA,KACS;AACT,EAAA,OAAA,CAAQ,MAAM,CAAA,EAAG,IAAA,CAAK,SAAS,CAAA,IAAA,EAAO,WAAW,CAAA,CAAE,CAAA;AAEnD,EAAA,IAAA,CAAK,gBAAgB,WAAW,CAAA;AAClC;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-codemod-lib",
3
- "version": "2.2.1",
3
+ "version": "2.2.3",
4
4
  "private": false,
5
5
  "keywords": [
6
6
  "typescript",
@@ -24,6 +24,10 @@
24
24
  "import": {
25
25
  "types": "./dist/types.d.mts",
26
26
  "default": "./dist/entry-point.mjs"
27
+ },
28
+ "default": {
29
+ "types": "./dist/types.d.mts",
30
+ "default": "./dist/entry-point.mjs"
27
31
  }
28
32
  }
29
33
  },
@@ -43,6 +47,8 @@
43
47
  "LICENSE"
44
48
  ],
45
49
  "scripts": {
50
+ "agents:gen": "tsx ./scripts/cmd/gen-agents-md.mts",
51
+ "agents:sync": "tsx ./scripts/cmd/sync-agent-config.mts",
46
52
  "build": "tsx ./scripts/cmd/build.mts",
47
53
  "build:min": "tsx ./scripts/cmd/build.mts --skip-check",
48
54
  "check:ext": "tsx ./scripts/cmd/check-ext.mts",
@@ -97,22 +103,21 @@
97
103
  "test:cov:ui": "vite preview --outDir ./coverage",
98
104
  "test:ui": "pnpm run z:vitest:node --ui",
99
105
  "testw": "pnpm run z:vitest:node watch",
100
- "tsc": "tsc --noEmit",
101
- "tscw": "tsc --noEmit --watch -p ./tsconfig.json",
102
- "type-check": "tsc --noEmit",
103
- "update-packages": "pnpm update --latest",
106
+ "tsc": "node ./node_modules/typescript-native/bin/tsc --noEmit",
107
+ "tscw": "node ./node_modules/typescript-native/bin/tsc --noEmit --watch -p ./tsconfig.json",
108
+ "type-check": "node ./node_modules/typescript-native/bin/tsc --noEmit",
109
+ "update-packages": "pnpm update --latest '!typescript'",
104
110
  "z:vitest": "vitest --config ./configs/vitest.config.mts",
105
111
  "z:vitest:node": "pnpm run z:vitest --project='Node.js'"
106
112
  },
107
113
  "dependencies": {
108
- "ts-data-forge": "^6.9.6",
114
+ "ts-data-forge": "^7.1.1",
109
115
  "ts-morph": "^28.0.0",
110
- "ts-type-forge": "^3.0.1"
116
+ "ts-type-forge": "^4.0.0"
111
117
  },
112
118
  "devDependencies": {
113
119
  "@rollup/plugin-replace": "6.0.3",
114
120
  "@rollup/plugin-strip": "3.0.4",
115
- "@rollup/plugin-typescript": "12.3.0",
116
121
  "@semantic-release/changelog": "6.0.3",
117
122
  "@semantic-release/commit-analyzer": "13.0.1",
118
123
  "@semantic-release/exec": "7.1.0",
@@ -120,35 +125,37 @@
120
125
  "@semantic-release/github": "12.0.8",
121
126
  "@semantic-release/npm": "13.1.5",
122
127
  "@semantic-release/release-notes-generator": "14.1.1",
123
- "@types/node": "25.9.2",
124
- "@vitest/browser-playwright": "4.1.5",
125
- "@vitest/coverage-v8": "4.1.5",
126
- "@vitest/ui": "4.1.5",
128
+ "@types/node": "26.1.0",
129
+ "@vitest/browser-playwright": "4.1.10",
130
+ "@vitest/coverage-v8": "4.1.10",
131
+ "@vitest/ui": "4.1.9",
127
132
  "cmd-ts": "0.15.0",
128
- "conventional-changelog-conventionalcommits": "9.3.1",
133
+ "conventional-changelog-conventionalcommits": "10.2.1",
129
134
  "cspell": "10.0.1",
130
135
  "dedent": "1.7.2",
131
- "eslint": "9.39.4",
132
- "eslint-config-typed": "4.9.11",
136
+ "esbuild": "0.28.1",
137
+ "eslint": "10.6.0",
138
+ "eslint-config-typed": "5.4.0",
133
139
  "github-settings-as-code": "1.2.9",
134
140
  "jiti": "2.7.0",
135
- "markdownlint": "0.40.0",
136
- "markdownlint-cli2": "0.22.1",
137
- "npm-run-all2": "8.0.4",
138
- "playwright": "1.60.0",
139
- "prettier": "3.8.3",
141
+ "markdownlint": "0.41.0",
142
+ "markdownlint-cli2": "0.23.0",
143
+ "npm-run-all2": "9.0.2",
144
+ "playwright": "1.61.1",
145
+ "prettier": "3.9.4",
140
146
  "prettier-plugin-organize-imports": "4.3.0",
141
147
  "prettier-plugin-packagejson": "3.0.2",
142
- "rollup": "4.61.1",
148
+ "rollup": "4.62.2",
149
+ "rollup-plugin-esbuild": "6.2.1",
143
150
  "semantic-release": "25.0.5",
144
151
  "ts-repo-utils": "10.1.2",
145
- "tslib": "2.8.1",
146
- "tsx": "4.22.3",
152
+ "tsx": "4.23.0",
147
153
  "typedoc": "0.28.19",
148
154
  "typedoc-github-theme": "0.4.0",
149
- "typescript": "5.9.3",
150
- "vite": "8.0.16",
151
- "vitest": "4.1.5"
155
+ "typescript": "6.0.3",
156
+ "typescript-native": "npm:typescript@7.0.1-rc",
157
+ "vite": "8.1.3",
158
+ "vitest": "4.1.10"
152
159
  },
153
160
  "peerDependencies": {
154
161
  "cmd-ts": "0.14.3",
@@ -166,12 +173,16 @@
166
173
  "optional": true
167
174
  }
168
175
  },
169
- "packageManager": "pnpm@10.33.4",
176
+ "packageManager": "pnpm@11.10.0+sha512.0b7f8b98060031904c017e3a41eb187a16d40eeb829b95c4f8cb03681761fc4ab53dd219115b9b447f4dce1a05a214764461e7d3703392a9f32f9511ce8c86c8",
170
177
  "engines": {
171
- "node": ">=22.18.0",
178
+ "node": ">=22.22.2",
172
179
  "pnpm": ">=9.0.0"
173
180
  },
174
181
  "volta": {
175
- "node": "25.9.0"
182
+ "node": "26.3.1"
183
+ },
184
+ "publishConfig": {
185
+ "access": "public",
186
+ "provenance": true
176
187
  }
177
188
  }
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import * as cmd from 'cmd-ts';
4
- import { Result } from 'ts-data-forge';
4
+ import { Arr, Result } from 'ts-data-forge';
5
5
  import { appendAsConstTransformer } from '../functions/index.mjs';
6
6
  import { runTransformerCLI } from './run-transformer-cli.mjs';
7
7
 
@@ -9,7 +9,7 @@ const transformer = appendAsConstTransformer();
9
9
 
10
10
  const cmdDef = cmd.command({
11
11
  name: transformer.name,
12
- version: '2.2.1',
12
+ version: '2.2.3',
13
13
  args: {
14
14
  baseDir: cmd.positional({
15
15
  type: cmd.string,
@@ -64,4 +64,4 @@ const cmdDef = cmd.command({
64
64
  },
65
65
  });
66
66
 
67
- await cmd.run(cmdDef, process.argv.slice(2));
67
+ await cmd.run(cmdDef, Arr.skip(process.argv, 2));
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import * as cmd from 'cmd-ts';
4
- import { Result } from 'ts-data-forge';
4
+ import { Arr, Result } from 'ts-data-forge';
5
5
  import { convertInterfaceToTypeTransformer } from '../functions/index.mjs';
6
6
  import { runTransformerCLI } from './run-transformer-cli.mjs';
7
7
 
@@ -9,7 +9,7 @@ const transformer = convertInterfaceToTypeTransformer();
9
9
 
10
10
  const cmdDef = cmd.command({
11
11
  name: transformer.name,
12
- version: '2.2.1',
12
+ version: '2.2.3',
13
13
  args: {
14
14
  baseDir: cmd.positional({
15
15
  type: cmd.string,
@@ -64,4 +64,4 @@ const cmdDef = cmd.command({
64
64
  },
65
65
  });
66
66
 
67
- await cmd.run(cmdDef, process.argv.slice(2));
67
+ await cmd.run(cmdDef, Arr.skip(process.argv, 2));