@codeperfect/eslint-plugin 3.0.0 → 3.2.0

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 (135) hide show
  1. package/dist/adapters/angular/angular-template-block-usage-utilities.d.ts +4 -0
  2. package/dist/adapters/angular/angular-template-block-usage-utilities.d.ts.map +1 -0
  3. package/dist/adapters/angular/angular-template-block-usage-utilities.js +69 -0
  4. package/dist/adapters/angular/angular-template-expression-utilities.d.ts +5 -0
  5. package/dist/adapters/angular/angular-template-expression-utilities.d.ts.map +1 -0
  6. package/dist/adapters/angular/angular-template-expression-utilities.js +121 -0
  7. package/dist/adapters/angular/angular-template-node-usage-utilities.d.ts +4 -0
  8. package/dist/adapters/angular/angular-template-node-usage-utilities.d.ts.map +1 -0
  9. package/dist/adapters/angular/angular-template-node-usage-utilities.js +47 -0
  10. package/dist/adapters/angular/angular-template-usage-context.d.ts +26 -0
  11. package/dist/adapters/angular/angular-template-usage-context.d.ts.map +1 -0
  12. package/dist/adapters/angular/angular-template-usage-context.js +12 -0
  13. package/dist/adapters/angular/index.d.ts +2 -0
  14. package/dist/adapters/angular/index.d.ts.map +1 -0
  15. package/dist/adapters/angular/index.js +2 -0
  16. package/dist/adapters/angular/no-unused-public-members-template-adapter.d.ts +15 -0
  17. package/dist/adapters/angular/no-unused-public-members-template-adapter.d.ts.map +1 -0
  18. package/dist/adapters/angular/no-unused-public-members-template-adapter.js +126 -0
  19. package/dist/adapters/angular/plugin.d.ts +12 -0
  20. package/dist/adapters/angular/plugin.d.ts.map +1 -0
  21. package/dist/adapters/angular/plugin.js +14 -0
  22. package/dist/adapters/index.d.ts +2 -0
  23. package/dist/adapters/index.d.ts.map +1 -0
  24. package/dist/adapters/index.js +2 -0
  25. package/dist/application/custom-rules.d.ts +3 -0
  26. package/dist/application/custom-rules.d.ts.map +1 -1
  27. package/dist/application/custom-rules.js +3 -2
  28. package/dist/application/index.d.ts +1 -1
  29. package/dist/application/index.d.ts.map +1 -1
  30. package/dist/application/index.js +2 -2
  31. package/dist/codeperfect-eslint-plugin-1.0.0.tgz +0 -0
  32. package/dist/domain/architecture/consistent-barrel-files/barrel-file-utilities.d.ts +0 -2
  33. package/dist/domain/architecture/consistent-barrel-files/barrel-file-utilities.d.ts.map +1 -1
  34. package/dist/domain/architecture/consistent-barrel-files/barrel-file-utilities.js +1 -2
  35. package/dist/domain/architecture/consistent-barrel-files/consistent-barrel-files-options.d.ts +0 -2
  36. package/dist/domain/architecture/consistent-barrel-files/consistent-barrel-files-options.d.ts.map +1 -1
  37. package/dist/domain/architecture/consistent-barrel-files/consistent-barrel-files-options.js +2 -10
  38. package/dist/domain/architecture/index.d.ts +1 -0
  39. package/dist/domain/architecture/index.d.ts.map +1 -1
  40. package/dist/domain/architecture/index.js +2 -1
  41. package/dist/domain/architecture/no-unused-public-members/index.d.ts +2 -0
  42. package/dist/domain/architecture/no-unused-public-members/index.d.ts.map +1 -0
  43. package/dist/domain/architecture/no-unused-public-members/index.js +2 -0
  44. package/dist/domain/architecture/no-unused-public-members/member-contract-utilities.d.ts +16 -0
  45. package/dist/domain/architecture/no-unused-public-members/member-contract-utilities.d.ts.map +1 -0
  46. package/dist/domain/architecture/no-unused-public-members/member-contract-utilities.js +102 -0
  47. package/dist/domain/architecture/no-unused-public-members/member-declaration-utilities.d.ts +34 -0
  48. package/dist/domain/architecture/no-unused-public-members/member-declaration-utilities.d.ts.map +1 -0
  49. package/dist/domain/architecture/no-unused-public-members/member-declaration-utilities.js +55 -0
  50. package/dist/domain/architecture/no-unused-public-members/member-host-utilities.d.ts +68 -0
  51. package/dist/domain/architecture/no-unused-public-members/member-host-utilities.d.ts.map +1 -0
  52. package/dist/domain/architecture/no-unused-public-members/member-host-utilities.js +195 -0
  53. package/dist/domain/architecture/no-unused-public-members/member-public-api-utilities.d.ts +30 -0
  54. package/dist/domain/architecture/no-unused-public-members/member-public-api-utilities.d.ts.map +1 -0
  55. package/dist/domain/architecture/no-unused-public-members/member-public-api-utilities.js +106 -0
  56. package/dist/domain/architecture/no-unused-public-members/member-usage-expression-reference-utilities.d.ts +16 -0
  57. package/dist/domain/architecture/no-unused-public-members/member-usage-expression-reference-utilities.d.ts.map +1 -0
  58. package/dist/domain/architecture/no-unused-public-members/member-usage-expression-reference-utilities.js +77 -0
  59. package/dist/domain/architecture/no-unused-public-members/member-usage-handoff-utilities.d.ts +28 -0
  60. package/dist/domain/architecture/no-unused-public-members/member-usage-handoff-utilities.d.ts.map +1 -0
  61. package/dist/domain/architecture/no-unused-public-members/member-usage-handoff-utilities.js +151 -0
  62. package/dist/domain/architecture/no-unused-public-members/member-usage-local-flow-utilities.d.ts +16 -0
  63. package/dist/domain/architecture/no-unused-public-members/member-usage-local-flow-utilities.d.ts.map +1 -0
  64. package/dist/domain/architecture/no-unused-public-members/member-usage-local-flow-utilities.js +151 -0
  65. package/dist/domain/architecture/no-unused-public-members/member-usage-reference-utilities.d.ts +29 -0
  66. package/dist/domain/architecture/no-unused-public-members/member-usage-reference-utilities.d.ts.map +1 -0
  67. package/dist/domain/architecture/no-unused-public-members/member-usage-reference-utilities.js +115 -0
  68. package/dist/domain/architecture/no-unused-public-members/member-usage-serialization-utilities.d.ts +30 -0
  69. package/dist/domain/architecture/no-unused-public-members/member-usage-serialization-utilities.d.ts.map +1 -0
  70. package/dist/domain/architecture/no-unused-public-members/member-usage-serialization-utilities.js +107 -0
  71. package/dist/domain/architecture/no-unused-public-members/member-usage-type-utilities.d.ts +64 -0
  72. package/dist/domain/architecture/no-unused-public-members/member-usage-type-utilities.d.ts.map +1 -0
  73. package/dist/domain/architecture/no-unused-public-members/member-usage-type-utilities.js +152 -0
  74. package/dist/domain/architecture/no-unused-public-members/member-usage-utilities.d.ts +22 -0
  75. package/dist/domain/architecture/no-unused-public-members/member-usage-utilities.d.ts.map +1 -0
  76. package/dist/domain/architecture/no-unused-public-members/member-usage-utilities.js +137 -0
  77. package/dist/domain/architecture/no-unused-public-members/member-usage-value-utilities.d.ts +43 -0
  78. package/dist/domain/architecture/no-unused-public-members/member-usage-value-utilities.d.ts.map +1 -0
  79. package/dist/domain/architecture/no-unused-public-members/member-usage-value-utilities.js +126 -0
  80. package/dist/domain/architecture/no-unused-public-members/member-utilities.d.ts +43 -0
  81. package/dist/domain/architecture/no-unused-public-members/member-utilities.d.ts.map +1 -0
  82. package/dist/domain/architecture/no-unused-public-members/member-utilities.js +52 -0
  83. package/dist/domain/architecture/no-unused-public-members/rule.d.ts +16 -0
  84. package/dist/domain/architecture/no-unused-public-members/rule.d.ts.map +1 -0
  85. package/dist/domain/architecture/no-unused-public-members/rule.js +88 -0
  86. package/dist/domain/docs/no-interface-member-docs/comment-utilities.js +4 -4
  87. package/dist/domain/docs/no-interface-member-docs/parameter-tags.d.ts.map +1 -1
  88. package/dist/domain/docs/no-interface-member-docs/parameter-tags.js +2 -2
  89. package/dist/domain/docs/no-interface-member-docs/parameter-utilities.js +4 -4
  90. package/dist/domain/docs/no-interface-member-docs/rule.d.ts.map +1 -1
  91. package/dist/domain/docs/no-interface-member-docs/rule.js +2 -5
  92. package/dist/domain/docs/require-example-language/example-utilities.d.ts +1 -7
  93. package/dist/domain/docs/require-example-language/example-utilities.d.ts.map +1 -1
  94. package/dist/domain/docs/require-example-language/example-utilities.js +4 -6
  95. package/dist/domain/docs/require-example-language/examples.d.ts.map +1 -1
  96. package/dist/domain/docs/require-example-language/examples.js +2 -4
  97. package/dist/domain/docs/require-example-language/reporting.d.ts.map +1 -1
  98. package/dist/domain/docs/require-example-language/reporting.js +1 -4
  99. package/dist/domain/docs/require-example-language/types.d.ts +0 -2
  100. package/dist/domain/docs/require-example-language/types.d.ts.map +1 -1
  101. package/dist/domain/docs/require-example-language/types.js +1 -1
  102. package/dist/domain/index.d.ts +1 -1
  103. package/dist/domain/index.d.ts.map +1 -1
  104. package/dist/domain/index.js +2 -2
  105. package/dist/domain/testing/aaa/analyzer.analysis.d.ts.map +1 -1
  106. package/dist/domain/testing/aaa/analyzer.analysis.js +2 -7
  107. package/dist/domain/testing/aaa/analyzer.assertions.js +2 -2
  108. package/dist/domain/testing/aaa/analyzer.classification.js +2 -2
  109. package/dist/domain/testing/aaa/types.d.ts +0 -4
  110. package/dist/domain/testing/aaa/types.d.ts.map +1 -1
  111. package/dist/domain/testing/aaa/types.js +1 -1
  112. package/dist/domain/testing/enforce-aaa-phase-purity/pattern-identifiers.d.ts.map +1 -1
  113. package/dist/domain/testing/enforce-aaa-phase-purity/pattern-identifiers.js +2 -7
  114. package/dist/domain/testing/prefer-vi-mocked-import/match-bindings.d.ts.map +1 -1
  115. package/dist/domain/testing/prefer-vi-mocked-import/match-bindings.js +5 -9
  116. package/dist/domain/testing/prefer-vi-mocked-import/match-collisions.d.ts.map +1 -1
  117. package/dist/domain/testing/prefer-vi-mocked-import/match-collisions.js +2 -7
  118. package/dist/domain/testing/prefer-vi-mocked-import/match-declarations.d.ts.map +1 -1
  119. package/dist/domain/testing/prefer-vi-mocked-import/match-declarations.js +5 -5
  120. package/dist/domain/testing/prefer-vi-mocked-import/match-imports.d.ts.map +1 -1
  121. package/dist/domain/testing/prefer-vi-mocked-import/match-imports.js +13 -20
  122. package/dist/domain/testing/prefer-vi-mocked-import/types.d.ts +0 -2
  123. package/dist/domain/testing/prefer-vi-mocked-import/types.d.ts.map +1 -1
  124. package/dist/domain/testing/prefer-vi-mocked-import/types.js +1 -1
  125. package/dist/domain/testing/require-test-companion/require-test-companion-options.js +3 -3
  126. package/dist/domain/testing/require-test-companion/rule.js +2 -2
  127. package/dist/index.d.ts +2 -1
  128. package/dist/index.d.ts.map +1 -1
  129. package/dist/index.js +3 -2
  130. package/dist/infrastructure/codeperfect-plugin.d.ts +2 -0
  131. package/dist/infrastructure/codeperfect-plugin.d.ts.map +1 -1
  132. package/dist/infrastructure/codeperfect-plugin.js +3 -2
  133. package/dist/infrastructure/presets.d.ts.map +1 -1
  134. package/dist/infrastructure/presets.js +3 -1
  135. package/package.json +36 -24
@@ -0,0 +1,151 @@
1
+ import * as ts from "typescript";
2
+ import { getCallArgumentType, getContextualPropertyType, isDeclarationOnlyMethod, isMemberHandoff, } from "./member-usage-type-utilities.js";
3
+ import { expressionCarriesMemberValue } from "./member-usage-value-utilities.js";
4
+ /**
5
+ * Checks whether a contextual property comes from an external declaration.
6
+ * @param objectType Contextual type of the containing object literal.
7
+ * @param propertyName Property name in the object literal.
8
+ * @param checker TypeScript type checker.
9
+ * @returns True when the contract is declared outside the project source.
10
+ * @example
11
+ * ```typescript
12
+ * const external = isExternalPropertyContract(objectType, "docs", checker);
13
+ * ```
14
+ */
15
+ const isExternalPropertyContract = (objectType, propertyName, checker) => {
16
+ const property = objectType === void 0
17
+ ? void 0
18
+ : checker.getPropertyOfType(objectType, propertyName);
19
+ return (property?.declarations?.some((declaration) => declaration.getSourceFile().isDeclarationFile) ?? false);
20
+ };
21
+ /**
22
+ * Checks whether a call resolves to a declaration with a local implementation.
23
+ * @param call Call expression to inspect.
24
+ * @param checker TypeScript type checker.
25
+ * @returns True when the resolved declaration has a body.
26
+ * @example
27
+ * ```typescript
28
+ * const implemented = hasCallImplementation(call, checker);
29
+ * ```
30
+ */
31
+ const hasCallImplementation = (call, checker) => {
32
+ const declaration = checker.getResolvedSignature(call)?.getDeclaration();
33
+ return (declaration !== void 0 &&
34
+ "body" in declaration &&
35
+ declaration.body !== void 0);
36
+ };
37
+ /**
38
+ * Checks whether an opaque value property is passed to a method contract.
39
+ * @param objectLiteral Object literal passed to the method.
40
+ * @param propertyName Property carrying the value.
41
+ * @param valueExpression Value assigned to the property.
42
+ * @param objectType Contextual type of the object literal.
43
+ * @param checker TypeScript type checker.
44
+ * @param member Member whose value is being handed off.
45
+ * @returns True when a declaration-only method receives the member as opaque data.
46
+ * @example
47
+ * ```typescript
48
+ * const handedOff = isOpaqueMethodContractHandoff(
49
+ * objectLiteral,
50
+ * "payload",
51
+ * value,
52
+ * type,
53
+ * checker,
54
+ * member,
55
+ * );
56
+ * ```
57
+ */
58
+ const isOpaqueMethodContractHandoff = (objectLiteral, propertyName, valueExpression, objectType, checker, member) => {
59
+ const call = objectLiteral.parent;
60
+ const declaration = ts.isCallExpression(call)
61
+ ? checker.getResolvedSignature(call)?.getDeclaration()
62
+ : void 0;
63
+ if (!ts.isCallExpression(call) ||
64
+ !call.arguments.includes(objectLiteral) ||
65
+ declaration === void 0 ||
66
+ !isDeclarationOnlyMethod(declaration)) {
67
+ return false;
68
+ }
69
+ const targetType = getContextualPropertyType(objectType, propertyName, objectLiteral, checker);
70
+ const isHttpRequestBody = propertyName === "body" &&
71
+ ts.isPropertyAccessExpression(call.expression) &&
72
+ call.expression.name.text === "request";
73
+ return (targetType !== void 0 &&
74
+ ((targetType.flags & ts.TypeFlags.Unknown) !== 0 ||
75
+ (isHttpRequestBody && (targetType.flags & ts.TypeFlags.Any) !== 0)) &&
76
+ expressionCarriesMemberValue(valueExpression, checker, member));
77
+ };
78
+ /**
79
+ * Checks whether a value is supplied to a typed external call boundary.
80
+ * @param node Candidate call expression.
81
+ * @param checker TypeScript type checker.
82
+ * @param member Member whose usage is being checked.
83
+ * @returns True when an external call contract accepts the member shape.
84
+ * @example
85
+ * ```typescript
86
+ * const used = isCallArgumentMember(node, checker, member);
87
+ * ```
88
+ */
89
+ const isCallArgumentMember = (node, checker, member) => {
90
+ if (!ts.isCallExpression(node) || hasCallImplementation(node, checker)) {
91
+ return false;
92
+ }
93
+ const declaration = checker.getResolvedSignature(node)?.getDeclaration();
94
+ return (declaration !== void 0 &&
95
+ node.arguments.some((argument) => {
96
+ const argumentType = getCallArgumentType(node, argument, checker);
97
+ const isOpaqueJsonBody = isDeclarationOnlyMethod(declaration) &&
98
+ ts.isPropertyAccessExpression(node.expression) &&
99
+ node.expression.name.text === "json" &&
100
+ node.arguments[0] === argument &&
101
+ argumentType !== void 0 &&
102
+ (argumentType.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0;
103
+ return ((isOpaqueJsonBody &&
104
+ expressionCarriesMemberValue(argument, checker, member)) ||
105
+ isMemberHandoff(argument, argumentType, member, checker));
106
+ }));
107
+ };
108
+ /**
109
+ * Checks whether a property value is forwarded into an external object contract.
110
+ * @param node Candidate outer object property.
111
+ * @param checker TypeScript type checker.
112
+ * @param member Member whose host value is being forwarded.
113
+ * @returns True when the receiving property accepts the host shape.
114
+ * @example
115
+ * ```typescript
116
+ * const used = isObjectContractHandoff(node, checker, member);
117
+ * ```
118
+ */
119
+ const isObjectContractHandoff = (node, checker, member) => {
120
+ if (ts.isPropertyAssignment(node) &&
121
+ ts.isObjectLiteralExpression(node.parent)) {
122
+ const name = node.name;
123
+ if (!ts.isIdentifier(name) && !ts.isStringLiteralLike(name)) {
124
+ return false;
125
+ }
126
+ const objectType = checker.getContextualType(node.parent);
127
+ if (isOpaqueMethodContractHandoff(node.parent, name.text, node.initializer, objectType, checker, member)) {
128
+ return true;
129
+ }
130
+ if (!isExternalPropertyContract(objectType, name.text, checker)) {
131
+ return false;
132
+ }
133
+ const targetType = getContextualPropertyType(objectType, name.text, node, checker);
134
+ return isMemberHandoff(node.initializer, targetType, member, checker);
135
+ }
136
+ if (ts.isShorthandPropertyAssignment(node) &&
137
+ ts.isObjectLiteralExpression(node.parent)) {
138
+ const objectType = checker.getContextualType(node.parent);
139
+ if (isOpaqueMethodContractHandoff(node.parent, node.name.text, node.name, objectType, checker, member)) {
140
+ return true;
141
+ }
142
+ if (!isExternalPropertyContract(objectType, node.name.text, checker)) {
143
+ return false;
144
+ }
145
+ const targetType = getContextualPropertyType(objectType, node.name.text, node, checker);
146
+ return isMemberHandoff(node.name, targetType, member, checker);
147
+ }
148
+ return false;
149
+ };
150
+ export { isCallArgumentMember, isObjectContractHandoff };
151
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVtYmVyLXVzYWdlLWhhbmRvZmYtdXRpbGl0aWVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2RvbWFpbi9hcmNoaXRlY3R1cmUvbm8tdW51c2VkLXB1YmxpYy1tZW1iZXJzL21lbWJlci11c2FnZS1oYW5kb2ZmLXV0aWxpdGllcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxNQUFNLFlBQVksQ0FBQztBQUlqQyxPQUFPLEVBQ0wsbUJBQW1CLEVBQ25CLHlCQUF5QixFQUN6Qix1QkFBdUIsRUFDdkIsZUFBZSxHQUNoQixNQUFNLCtCQUErQixDQUFDO0FBQ3ZDLE9BQU8sRUFBRSw0QkFBNEIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBRTlFOzs7Ozs7Ozs7O0dBVUc7QUFDSCxNQUFNLDBCQUEwQixHQUFHLENBQ2pDLFVBQStCLEVBQy9CLFlBQW9CLEVBQ3BCLE9BQXVCLEVBQ2QsRUFBRTtJQUNYLE1BQU0sUUFBUSxHQUNaLFVBQVUsS0FBSyxLQUFLLENBQUM7UUFDbkIsQ0FBQyxDQUFDLEtBQUssQ0FBQztRQUNSLENBQUMsQ0FBQyxPQUFPLENBQUMsaUJBQWlCLENBQUMsVUFBVSxFQUFFLFlBQVksQ0FBQyxDQUFDO0lBRTFELE9BQU8sQ0FDTCxRQUFRLEVBQUUsWUFBWSxFQUFFLElBQUksQ0FDMUIsQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDLFdBQVcsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxpQkFBaUIsQ0FDL0QsSUFBSSxLQUFLLENBQ1gsQ0FBQztBQUNKLENBQUMsQ0FBQztBQUVGOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0scUJBQXFCLEdBQUcsQ0FDNUIsSUFBdUIsRUFDdkIsT0FBdUIsRUFDZCxFQUFFO0lBQ1gsTUFBTSxXQUFXLEdBQUcsT0FBTyxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxFQUFFLGNBQWMsRUFBRSxDQUFDO0lBRXpFLE9BQU8sQ0FDTCxXQUFXLEtBQUss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Q2YsQ0FBQyxDQUFDO0FBRUYsT0FBTyxFQUFFLG9CQUFvQixFQUFFLHVCQUF1QixFQUFFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyB0cyBmcm9tIFwidHlwZXNjcmlwdFwiO1xuXG5pbXBvcnQgdHlwZSB7IFB1YmxpY01lbWJlciB9IGZyb20gXCIuL21lbWJlci1kZWNsYXJhdGlvbi11dGlsaXRpZXNcIjtcblxuaW1wb3J0IHtcbiAgZ2V0Q2FsbEFyZ3VtZW50VHlwZSxcbiAgZ2V0Q29udGV4dHVhbFByb3BlcnR5VHlwZSxcbiAgaXNEZWNsYXJhdGlvbk9ubHlNZXRob2QsXG4gIGlzTWVtYmVySGFuZG9mZixcbn0gZnJvbSBcIi4vbWVtYmVyLXVzYWdlLXR5cGUtdXRpbGl0aWVzXCI7XG5pbXBvcnQgeyBleHByZXNzaW9uQ2Fycmllc01lbWJlclZhbHVlIH0gZnJvbSBcIi4vbWVtYmVyLXVzYWdlLXZhbHVlLXV0aWxpdGllc1wiO1xuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIGEgY29udGV4dHVhbCBwcm9wZXJ0eSBjb21lcyBmcm9tIGFuIGV4dGVybmFsIGRlY2xhcmF0aW9uLlxuICogQHBhcmFtIG9iamVjdFR5cGUgQ29udGV4dHVhbCB0eXBlIG9mIHRoZSBjb250YWluaW5nIG9iamVjdCBsaXRlcmFsLlxuICogQHBhcmFtIHByb3BlcnR5TmFtZSBQcm9wZXJ0eSBuYW1lIGluIHRoZSBvYmplY3QgbGl0ZXJhbC5cbiAqIEBwYXJhbSBjaGVja2VyIFR5cGVTY3JpcHQgdHlwZSBjaGVja2VyLlxuICogQHJldHVybnMgVHJ1ZSB3aGVuIHRoZSBjb250cmFjdCBpcyBkZWNsYXJlZCBvdXRzaWRlIHRoZSBwcm9qZWN0IHNvdXJjZS5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBleHRlcm5hbCA9IGlzRXh0ZXJuYWxQcm9wZXJ0eUNvbnRyYWN0KG9iamVjdFR5cGUsIFwiZG9jc1wiLCBjaGVja2VyKTtcbiAqIGBgYFxuICovXG5jb25zdCBpc0V4dGVybmFsUHJvcGVydHlDb250cmFjdCA9IChcbiAgb2JqZWN0VHlwZTogdHMuVHlwZSB8IHVuZGVmaW5lZCxcbiAgcHJvcGVydHlOYW1lOiBzdHJpbmcsXG4gIGNoZWNrZXI6IHRzLlR5cGVDaGVja2VyLFxuKTogYm9vbGVhbiA9PiB7XG4gIGNvbnN0IHByb3BlcnR5ID1cbiAgICBvYmplY3RUeXBlID09PSB2b2lkIDBcbiAgICAgID8gdm9pZCAwXG4gICAgICA6IGNoZWNrZXIuZ2V0UHJvcGVydHlPZlR5cGUob2JqZWN0VHlwZSwgcHJvcGVydHlOYW1lKTtcblxuICByZXR1cm4gKFxuICAgIHByb3BlcnR5Py5kZWNsYXJhdGlvbnM/LnNvbWUoXG4gICAgICAoZGVjbGFyYXRpb24pID0+IGRlY2xhcmF0aW9uLmdldFNvdXJjZUZpbGUoKS5pc0RlY2xhcmF0aW9uRmlsZSxcbiAgICApID8/IGZhbHNlXG4gICk7XG59O1xuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIGEgY2FsbCByZXNvbHZlcyB0byBhIGRlY2xhcmF0aW9uIHdpdGggYSBsb2NhbCBpbXBsZW1lbnRhdGlvbi5cbiAqIEBwYXJhbSBjYWxsIENhbGwgZXhwcmVzc2lvbiB0byBpbnNwZWN0LlxuICogQHBhcmFtIGNoZWNrZXIgVHlwZVNjcmlwdCB0eXBlIGNoZWNrZXIuXG4gKiBAcmV0dXJucyBUcnVlIHdoZW4gdGhlIHJlc29sdmVkIGRlY2xhcmF0aW9uIGhhcyBhIGJvZHkuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgaW1wbGVtZW50ZWQgPSBoYXNDYWxsSW1wbGVtZW50YXRpb24oY2FsbCwgY2hlY2tlcik7XG4gKiBgYGBcbiAqL1xuY29uc3QgaGFzQ2FsbEltcGxlbWVudGF0aW9uID0gKFxuICBjYWxsOiB0cy5DYWxsRXhwcmVzc2lvbixcbiAgY2hlY2tlcjogdHMuVHlwZUNoZWNrZXIsXG4pOiBib29sZWFuID0+IHtcbiAgY29uc3QgZGVjbGFyYXRpb24gPSBjaGVja2VyLmdldFJlc29sdmVkU2lnbmF0dXJlKGNhbGwpPy5nZXREZWNsYXJhdGlvbigpO1xuXG4gIHJldHVybiAoXG4gICAgZGVjbGFyYXRpb24gIT09IHZvaWQgMCAmJlxuICAgIFwiYm9keVwiIGluIGRlY2xhcmF0aW9uICYmXG4gICAgZGVjbGFyYXRpb24uYm9keSAhPT0gdm9pZCAwXG4gICk7XG59O1xuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIGFuIG9wYXF1ZSB2YWx1ZSBwcm9wZXJ0eSBpcyBwYXNzZWQgdG8gYSBtZXRob2QgY29udHJhY3QuXG4gKiBAcGFyYW0gb2JqZWN0TGl0ZXJhbCBPYmplY3QgbGl0ZXJhbCBwYXNzZWQgdG8gdGhlIG1ldGhvZC5cbiAqIEBwYXJhbSBwcm9wZXJ0eU5hbWUgUHJvcGVydHkgY2FycnlpbmcgdGhlIHZhbHVlLlxuICogQHBhcmFtIHZhbHVlRXhwcmVzc2lvbiBWYWx1ZSBhc3NpZ25lZCB0byB0aGUgcHJvcGVydHkuXG4gKiBAcGFyYW0gb2JqZWN0VHlwZSBDb250ZXh0dWFsIHR5cGUgb2YgdGhlIG9iamVjdCBsaXRlcmFsLlxuICogQHBhcmFtIGNoZWNrZXIgVHlwZVNjcmlwdCB0eXBlIGNoZWNrZXIuXG4gKiBAcGFyYW0gbWVtYmVyIE1lbWJlciB3aG9zZSB2YWx1ZSBpcyBiZWluZyBoYW5kZWQgb2ZmLlxuICogQHJldHVybnMgVHJ1ZSB3aGVuIGEgZGVjbGFyYXRpb24tb25seSBtZXRob2QgcmVjZWl2ZXMgdGhlIG1lbWJlciBhcyBvcGFxdWUgZGF0YS5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBoYW5kZWRPZmYgPSBpc09wYXF1ZU1ldGhvZENvbnRyYWN0SGFuZG9mZihcbiAqICAgb2JqZWN0TGl0ZXJhbCxcbiAqICAgXCJwYXlsb2FkXCIsXG4gKiAgIHZhbHVlLFxuICogICB0eXBlLFxuICogICBjaGVja2VyLFxuICogICBtZW1iZXIsXG4gKiApO1xuICogYGBgXG4gKi9cbmNvbnN0IGlzT3BhcXVlTWV0aG9kQ29udHJhY3RIYW5kb2ZmID0gKFxuICBvYmplY3RMaXRlcmFsOiB0cy5PYmplY3RMaXRlcmFsRXhwcmVzc2lvbixcbiAgcHJvcGVydHlOYW1lOiBzdHJpbmcsXG4gIHZhbHVlRXhwcmVzc2lvbjogdHMuRXhwcmVzc2lvbixcbiAgb2JqZWN0VHlwZTogdHMuVHlwZSB8IHVuZGVmaW5lZCxcbiAgY2hlY2tlcjogdHMuVHlwZUNoZWNrZXIsXG4gIG1lbWJlcjogUHVibGljTWVtYmVyLFxuKTogYm9vbGVhbiA9PiB7XG4gIGNvbnN0IGNhbGwgPSBvYmplY3RMaXRlcmFsLnBhcmVudDtcbiAgY29uc3QgZGVjbGFyYXRpb24gPSB0cy5pc0NhbGxFeHByZXNzaW9uKGNhbGwpXG4gICAgPyBjaGVja2VyLmdldFJlc29sdmVkU2lnbmF0dXJlKGNhbGwpPy5nZXREZWNsYXJhdGlvbigpXG4gICAgOiB2b2lkIDA7XG5cbiAgaWYgKFxuICAgICF0cy5pc0NhbGxFeHByZXNzaW9uKGNhbGwpIHx8XG4gICAgIWNhbGwuYXJndW1lbnRzLmluY2x1ZGVzKG9iamVjdExpdGVyYWwpIHx8XG4gICAgZGVjbGFyYXRpb24gPT09IHZvaWQgMCB8fFxuICAgICFpc0RlY2xhcmF0aW9uT25seU1ldGhvZChkZWNsYXJhdGlvbilcbiAgKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgY29uc3QgdGFyZ2V0VHlwZSA9IGdldENvbnRleHR1YWxQcm9wZXJ0eVR5cGUoXG4gICAgb2JqZWN0VHlwZSxcbiAgICBwcm9wZXJ0eU5hbWUsXG4gICAgb2JqZWN0TGl0ZXJhbCxcbiAgICBjaGVja2VyLFxuICApO1xuICBjb25zdCBpc0h0dHBSZXF1ZXN0Qm9keSA9XG4gICAgcHJvcGVydHlOYW1lID09PSBcImJvZHlcIiAmJlxuICAgIHRzLmlzUHJvcGVydHlBY2Nlc3NFeHByZXNzaW9uKGNhbGwuZXhwcmVzc2lvbikgJiZcbiAgICBjYWxsLmV4cHJlc3Npb24ubmFtZS50ZXh0ID09PSBcInJlcXVlc3RcIjtcblxuICByZXR1cm4gKFxuICAgIHRhcmdldFR5cGUgIT09IHZvaWQgMCAmJlxuICAgICgodGFyZ2V0VHlwZS5mbGFncyAmIHRzLlR5cGVGbGFncy5Vbmtub3duKSAhPT0gMCB8fFxuICAgICAgKGlzSHR0cFJlcXVlc3RCb2R5ICYmICh0YXJnZXRUeXBlLmZsYWdzICYgdHMuVHlwZUZsYWdzLkFueSkgIT09IDApKSAmJlxuICAgIGV4cHJlc3Npb25DYXJyaWVzTWVtYmVyVmFsdWUodmFsdWVFeHByZXNzaW9uLCBjaGVja2VyLCBtZW1iZXIpXG4gICk7XG59O1xuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIGEgdmFsdWUgaXMgc3VwcGxpZWQgdG8gYSB0eXBlZCBleHRlcm5hbCBjYWxsIGJvdW5kYXJ5LlxuICogQHBhcmFtIG5vZGUgQ2FuZGlkYXRlIGNhbGwgZXhwcmVzc2lvbi5cbiAqIEBwYXJhbSBjaGVja2VyIFR5cGVTY3JpcHQgdHlwZSBjaGVja2VyLlxuICogQHBhcmFtIG1lbWJlciBNZW1iZXIgd2hvc2UgdXNhZ2UgaXMgYmVpbmcgY2hlY2tlZC5cbiAqIEByZXR1cm5zIFRydWUgd2hlbiBhbiBleHRlcm5hbCBjYWxsIGNvbnRyYWN0IGFjY2VwdHMgdGhlIG1lbWJlciBzaGFwZS5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCB1c2VkID0gaXNDYWxsQXJndW1lbnRNZW1iZXIobm9kZSwgY2hlY2tlciwgbWVtYmVyKTtcbiAqIGBgYFxuICovXG5jb25zdCBpc0NhbGxBcmd1bWVudE1lbWJlciA9IChcbiAgbm9kZTogdHMuTm9kZSxcbiAgY2hlY2tlcjogdHMuVHlwZUNoZWNrZXIsXG4gIG1lbWJlcjogUHVibGljTWVtYmVyLFxuKTogYm9vbGVhbiA9PiB7XG4gIGlmICghdHMuaXNDYWxsRXhwcmVzc2lvbihub2RlKSB8fCBoYXNDYWxsSW1wbGVtZW50YXRpb24obm9kZSwgY2hlY2tlcikpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBkZWNsYXJhdGlvbiA9IGNoZWNrZXIuZ2V0UmVzb2x2ZWRTaWduYXR1cmUobm9kZSk/LmdldERlY2xhcmF0aW9uKCk7XG5cbiAgcmV0dXJuIChcbiAgICBkZWNsYXJhdGlvbiAhPT0gdm9pZCAwICYmXG4gICAgbm9kZS5hcmd1bWVudHMuc29tZSgoYXJndW1lbnQpID0+IHtcbiAgICAgIGNvbnN0IGFyZ3VtZW50VHlwZSA9IGdldENhbGxBcmd1bWVudFR5cGUobm9kZSwgYXJndW1lbnQsIGNoZWNrZXIpO1xuICAgICAgY29uc3QgaXNPcGFxdWVKc29uQm9keSA9XG4gICAgICAgIGlzRGVjbGFyYXRpb25Pbmx5TWV0aG9kKGRlY2xhcmF0aW9uKSAmJlxuICAgICAgICB0cy5pc1Byb3BlcnR5QWNjZXNzRXhwcmVzc2lvbihub2RlLmV4cHJlc3Npb24pICYmXG4gICAgICAgIG5vZGUuZXhwcmVzc2lvbi5uYW1lLnRleHQgPT09IFwianNvblwiICYmXG4gICAgICAgIG5vZGUuYXJndW1lbnRzWzBdID09PSBhcmd1bWVudCAmJlxuICAgICAgICBhcmd1bWVudFR5cGUgIT09IHZvaWQgMCAmJlxuICAgICAgICAoYXJndW1lbnRUeXBlLmZsYWdzICYgKHRzLlR5cGVGbGFncy5BbnkgfCB0cy5UeXBlRmxhZ3MuVW5rbm93bikpICE9PSAwO1xuXG4gICAgICByZXR1cm4gKFxuICAgICAgICAoaXNPcGFxdWVKc29uQm9keSAmJlxuICAgICAgICAgIGV4cHJlc3Npb25DYXJyaWVzTWVtYmVyVmFsdWUoYXJndW1lbnQsIGNoZWNrZXIsIG1lbWJlcikpIHx8XG4gICAgICAgIGlzTWVtYmVySGFuZG9mZihhcmd1bWVudCwgYXJndW1lbnRUeXBlLCBtZW1iZXIsIGNoZWNrZXIpXG4gICAgICApO1xuICAgIH0pXG4gICk7XG59O1xuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIGEgcHJvcGVydHkgdmFsdWUgaXMgZm9yd2FyZGVkIGludG8gYW4gZXh0ZXJuYWwgb2JqZWN0IGNvbnRyYWN0LlxuICogQHBhcmFtIG5vZGUgQ2FuZGlkYXRlIG91dGVyIG9iamVjdCBwcm9wZXJ0eS5cbiAqIEBwYXJhbSBjaGVja2VyIFR5cGVTY3JpcHQgdHlwZSBjaGVja2VyLlxuICogQHBhcmFtIG1lbWJlciBNZW1iZXIgd2hvc2UgaG9zdCB2YWx1ZSBpcyBiZWluZyBmb3J3YXJkZWQuXG4gKiBAcmV0dXJucyBUcnVlIHdoZW4gdGhlIHJlY2VpdmluZyBwcm9wZXJ0eSBhY2NlcHRzIHRoZSBob3N0IHNoYXBlLlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHVzZWQgPSBpc09iamVjdENvbnRyYWN0SGFuZG9mZihub2RlLCBjaGVja2VyLCBtZW1iZXIpO1xuICogYGBgXG4gKi9cbmNvbnN0IGlzT2JqZWN0Q29udHJhY3RIYW5kb2ZmID0gKFxuICBub2RlOiB0cy5Ob2RlLFxuICBjaGVja2VyOiB0cy5UeXBlQ2hlY2tlcixcbiAgbWVtYmVyOiBQdWJsaWNNZW1iZXIsXG4pOiBib29sZWFuID0+IHtcbiAgaWYgKFxuICAgIHRzLmlzUHJvcGVydHlBc3NpZ25tZW50KG5vZGUpICYmXG4gICAgdHMuaXNPYmplY3RMaXRlcmFsRXhwcmVzc2lvbihub2RlLnBhcmVudClcbiAgKSB7XG4gICAgY29uc3QgbmFtZSA9IG5vZGUubmFtZTtcblxuICAgIGlmICghdHMuaXNJZGVudGlmaWVyKG5hbWUpICYmICF0cy5pc1N0cmluZ0xpdGVyYWxMaWtlKG5hbWUpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgY29uc3Qgb2JqZWN0VHlwZSA9IGNoZWNrZXIuZ2V0Q29udGV4dHVhbFR5cGUobm9kZS5wYXJlbnQpO1xuXG4gICAgaWYgKFxuICAgICAgaXNPcGFxdWVNZXRob2RDb250cmFjdEhhbmRvZmYoXG4gICAgICAgIG5vZGUucGFyZW50LFxuICAgICAgICBuYW1lLnRleHQsXG4gICAgICAgIG5vZGUuaW5pdGlhbGl6ZXIsXG4gICAgICAgIG9iamVjdFR5cGUsXG4gICAgICAgIGNoZWNrZXIsXG4gICAgICAgIG1lbWJlcixcbiAgICAgIClcbiAgICApIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGlmICghaXNFeHRlcm5hbFByb3BlcnR5Q29udHJhY3Qob2JqZWN0VHlwZSwgbmFtZS50ZXh0LCBjaGVja2VyKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IHRhcmdldFR5cGUgPSBnZXRDb250ZXh0dWFsUHJvcGVydHlUeXBlKFxuICAgICAgb2JqZWN0VHlwZSxcbiAgICAgIG5hbWUudGV4dCxcbiAgICAgIG5vZGUsXG4gICAgICBjaGVja2VyLFxuICAgICk7XG5cbiAgICByZXR1cm4gaXNNZW1iZXJIYW5kb2ZmKG5vZGUuaW5pdGlhbGl6ZXIsIHRhcmdldFR5cGUsIG1lbWJlciwgY2hlY2tlcik7XG4gIH1cblxuICBpZiAoXG4gICAgdHMuaXNTaG9ydGhhbmRQcm9wZXJ0eUFzc2lnbm1lbnQobm9kZSkgJiZcbiAgICB0cy5pc09iamVjdExpdGVyYWxFeHByZXNzaW9uKG5vZGUucGFyZW50KVxuICApIHtcbiAgICBjb25zdCBvYmplY3RUeXBlID0gY2hlY2tlci5nZXRDb250ZXh0dWFsVHlwZShub2RlLnBhcmVudCk7XG5cbiAgICBpZiAoXG4gICAgICBpc09wYXF1ZU1ldGhvZENvbnRyYWN0SGFuZG9mZihcbiAgICAgICAgbm9kZS5wYXJlbnQsXG4gICAgICAgIG5vZGUubmFtZS50ZXh0LFxuICAgICAgICBub2RlLm5hbWUsXG4gICAgICAgIG9iamVjdFR5cGUsXG4gICAgICAgIGNoZWNrZXIsXG4gICAgICAgIG1lbWJlcixcbiAgICAgIClcbiAgICApIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGlmICghaXNFeHRlcm5hbFByb3BlcnR5Q29udHJhY3Qob2JqZWN0VHlwZSwgbm9kZS5uYW1lLnRleHQsIGNoZWNrZXIpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgY29uc3QgdGFyZ2V0VHlwZSA9IGdldENvbnRleHR1YWxQcm9wZXJ0eVR5cGUoXG4gICAgICBvYmplY3RUeXBlLFxuICAgICAgbm9kZS5uYW1lLnRleHQsXG4gICAgICBub2RlLFxuICAgICAgY2hlY2tlcixcbiAgICApO1xuXG4gICAgcmV0dXJuIGlzTWVtYmVySGFuZG9mZihub2RlLm5hbWUsIHRhcmdldFR5cGUsIG1lbWJlciwgY2hlY2tlcik7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59O1xuXG5leHBvcnQgeyBpc0NhbGxBcmd1bWVudE1lbWJlciwgaXNPYmplY3RDb250cmFjdEhhbmRvZmYgfTtcbiJdfQ==
@@ -0,0 +1,16 @@
1
+ import * as ts from "typescript";
2
+ import type { PublicMember } from "./member-declaration-utilities.js";
3
+ /**
4
+ * Checks whether a local call forwards a member-bearing value to an HTTP body.
5
+ * @param node Candidate local call expression.
6
+ * @param checker TypeScript type checker.
7
+ * @param member Member whose value is being transmitted.
8
+ * @returns True when the argument reaches an opaque request body contract.
9
+ * @example
10
+ * ```typescript
11
+ * const transmitted = isLocalCallArgumentTransmitted(call, checker, member);
12
+ * ```
13
+ */
14
+ declare const isLocalCallArgumentTransmitted: (node: ts.Node, checker: ts.TypeChecker, member: PublicMember) => boolean;
15
+ export { isLocalCallArgumentTransmitted };
16
+ //# sourceMappingURL=member-usage-local-flow-utilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"member-usage-local-flow-utilities.d.ts","sourceRoot":"","sources":["../../../../src/domain/architecture/no-unused-public-members/member-usage-local-flow-utilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAMnE;;;;;;;;;;GAUG;AACH,QAAA,MAAM,8BAA8B,GAClC,MAAM,EAAE,CAAC,IAAI,EACb,SAAS,EAAE,CAAC,WAAW,EACvB,QAAQ,YAAY,KACnB,OA+BF,CAAC;AAwKF,OAAO,EAAE,8BAA8B,EAAE,CAAC"}
@@ -0,0 +1,151 @@
1
+ import * as ts from "typescript";
2
+ import { expressionReferencesSymbol } from "./member-usage-expression-reference-utilities.js";
3
+ import { isDeclarationOnlyMethod } from "./member-usage-type-utilities.js";
4
+ import { expressionCarriesMemberValue } from "./member-usage-value-utilities.js";
5
+ /**
6
+ * Checks whether a local call forwards a member-bearing value to an HTTP body.
7
+ * @param node Candidate local call expression.
8
+ * @param checker TypeScript type checker.
9
+ * @param member Member whose value is being transmitted.
10
+ * @returns True when the argument reaches an opaque request body contract.
11
+ * @example
12
+ * ```typescript
13
+ * const transmitted = isLocalCallArgumentTransmitted(call, checker, member);
14
+ * ```
15
+ */
16
+ const isLocalCallArgumentTransmitted = (node, checker, member) => {
17
+ if (!ts.isCallExpression(node)) {
18
+ return false;
19
+ }
20
+ const declaration = checker.getResolvedSignature(node)?.getDeclaration();
21
+ if (!hasFunctionBody(declaration)) {
22
+ return false;
23
+ }
24
+ return node.arguments.some((argument, argumentIndex) => {
25
+ const parameter = declaration.parameters[Math.min(argumentIndex, declaration.parameters.length - 1)];
26
+ const parameterSymbol = parameter === void 0 || !ts.isIdentifier(parameter.name)
27
+ ? void 0
28
+ : checker.getSymbolAtLocation(parameter.name);
29
+ const carries = expressionCarriesMemberValue(argument, checker, member);
30
+ const reachesBody = parameterSymbol !== void 0 &&
31
+ localParameterReachesRequestBody(declaration, parameterSymbol, checker, new Map());
32
+ return parameterSymbol !== void 0 && carries && reachesBody;
33
+ });
34
+ };
35
+ /**
36
+ * Checks whether a local parameter reaches a declared HTTP request body.
37
+ * @param declaration Local function containing the parameter.
38
+ * @param parameterSymbol Parameter symbol whose value is traced.
39
+ * @param checker TypeScript type checker.
40
+ * @param visitedDeclarations Function declarations already inspected.
41
+ * @returns True when the parameter reaches an opaque request body.
42
+ * @example
43
+ * ```typescript
44
+ * const reachesBody = localParameterReachesRequestBody(
45
+ * declaration,
46
+ * parameterSymbol,
47
+ * checker,
48
+ * new Set(),
49
+ * );
50
+ * ```
51
+ */
52
+ const localParameterReachesRequestBody = (declaration, parameterSymbol, checker, visitedDeclarations) => {
53
+ if (!hasFunctionBody(declaration)) {
54
+ return false;
55
+ }
56
+ const visitedParameters = visitedDeclarations.get(declaration) ?? new Set();
57
+ if (visitedParameters.has(parameterSymbol)) {
58
+ return false;
59
+ }
60
+ visitedParameters.add(parameterSymbol);
61
+ visitedDeclarations.set(declaration, visitedParameters);
62
+ const inspect = (node) => {
63
+ if (ts.isCallExpression(node)) {
64
+ const isBody = isOpaqueRequestBodyHandoff(node, parameterSymbol, checker);
65
+ if (isBody) {
66
+ return true;
67
+ }
68
+ const nestedDeclaration = checker
69
+ .getResolvedSignature(node)
70
+ ?.getDeclaration();
71
+ if (hasFunctionBody(nestedDeclaration)) {
72
+ for (const [argumentIndex, argument] of node.arguments.entries()) {
73
+ const references = expressionReferencesSymbol(argument, parameterSymbol, checker);
74
+ if (!references) {
75
+ continue;
76
+ }
77
+ const nestedParameter = nestedDeclaration.parameters[Math.min(argumentIndex, nestedDeclaration.parameters.length - 1)];
78
+ const nestedParameterSymbol = nestedParameter === void 0 || !ts.isIdentifier(nestedParameter.name)
79
+ ? void 0
80
+ : checker.getSymbolAtLocation(nestedParameter.name);
81
+ if (nestedParameterSymbol !== void 0 &&
82
+ localParameterReachesRequestBody(nestedDeclaration, nestedParameterSymbol, checker, visitedDeclarations)) {
83
+ return true;
84
+ }
85
+ }
86
+ }
87
+ }
88
+ return ts.forEachChild(node, inspect);
89
+ };
90
+ return inspect(declaration.body) === true;
91
+ };
92
+ /**
93
+ * Checks whether a request call sends the traced parameter as opaque body data.
94
+ * @param call Candidate call expression.
95
+ * @param parameterSymbol Parameter symbol whose value is traced.
96
+ * @param checker TypeScript type checker.
97
+ * @returns True when a declaration-only request method accepts the value as body.
98
+ * @example
99
+ * ```typescript
100
+ * const opaque = isOpaqueRequestBodyHandoff(call, parameterSymbol, checker);
101
+ * ```
102
+ */
103
+ const isOpaqueRequestBodyHandoff = (call, parameterSymbol, checker) => {
104
+ const declaration = checker.getResolvedSignature(call)?.getDeclaration();
105
+ if (declaration === void 0 ||
106
+ !isDeclarationOnlyMethod(declaration) ||
107
+ !ts.isPropertyAccessExpression(call.expression) ||
108
+ call.expression.name.text !== "request") {
109
+ return false;
110
+ }
111
+ return call.arguments.some((argument) => {
112
+ if (!ts.isObjectLiteralExpression(argument)) {
113
+ return false;
114
+ }
115
+ const optionsType = checker.getContextualType(argument);
116
+ const requestOptionsType = optionsType === void 0 ? void 0 : checker.getNonNullableType(optionsType);
117
+ const bodyProperty = requestOptionsType === void 0
118
+ ? void 0
119
+ : checker.getPropertyOfType(requestOptionsType, "body");
120
+ if (bodyProperty === void 0) {
121
+ return false;
122
+ }
123
+ const bodyType = checker.getTypeOfSymbolAtLocation(bodyProperty, argument);
124
+ if ((bodyType.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) === 0) {
125
+ return false;
126
+ }
127
+ return argument.properties.some((property) => {
128
+ return ts.isPropertyAssignment(property) &&
129
+ ts.isIdentifier(property.name) &&
130
+ property.name.text === "body"
131
+ ? expressionReferencesSymbol(property.initializer, parameterSymbol, checker)
132
+ : ts.isShorthandPropertyAssignment(property) &&
133
+ property.name.text === "body" &&
134
+ expressionReferencesSymbol(property.name, parameterSymbol, checker);
135
+ });
136
+ });
137
+ };
138
+ /**
139
+ * Narrows a function-like declaration to one with a body.
140
+ * @param declaration Candidate call signature declaration.
141
+ * @returns Whether the declaration has a function body.
142
+ * @example
143
+ * ```typescript
144
+ * if (hasFunctionBody(declaration)) inspect(declaration.body);
145
+ * ```
146
+ */
147
+ const hasFunctionBody = (declaration) => declaration !== void 0 &&
148
+ "body" in declaration &&
149
+ declaration.body !== void 0;
150
+ export { isLocalCallArgumentTransmitted };
151
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVtYmVyLXVzYWdlLWxvY2FsLWZsb3ctdXRpbGl0aWVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2RvbWFpbi9hcmNoaXRlY3R1cmUvbm8tdW51c2VkLXB1YmxpYy1tZW1iZXJzL21lbWJlci11c2FnZS1sb2NhbC1mbG93LXV0aWxpdGllcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxNQUFNLFlBQVksQ0FBQztBQUlqQyxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSwrQ0FBK0MsQ0FBQztBQUMzRixPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUN4RSxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUU5RTs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBTSw4QkFBOEIsR0FBRyxDQUNyQyxJQUFhLEVBQ2IsT0FBdUIsRUFDdkIsTUFBb0IsRUFDWCxFQUFFO0lBQ1gsSUFBSSxDQUFDLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQy9CLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVELE1BQU0sV0FBVyxHQUFHLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsRUFBRSxjQUFjLEVBQUUsQ0FBQztJQUN6RSxJQUFJLENBQUMsZUFBZSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7UUFDbEMsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLFFBQVEsRUFBRSxhQUFhLEVBQUUsRUFBRTtRQUNyRCxNQUFNLFNBQVMsR0FDYixXQUFXLENBQUMsVUFBVSxDQUNwQixJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxXQUFXLENBQUMsVUFBVSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FDM0QsQ0FBQztRQUNK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QWUsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUM1RSxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDO0FBRUY7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLGVBQWUsR0FBRyxDQUN0QixXQUFnRCxFQUNtQixFQUFFLENBQ3JFLFdBQVcsS0FBSyxLQUFLLENBQUM7SUFDdEIsTUFBTSxJQUFJLFdBQVc7SUFDckIsV0FBVyxDQUFDLElBQUksS0FBSyxLQUFLLENBQUMsQ0FBQztBQUU5QixPQUFPLEVBQUUsOEJBQThCLEVBQUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIHRzIGZyb20gXCJ0eXBlc2NyaXB0XCI7XG5cbmltcG9ydCB0eXBlIHsgUHVibGljTWVtYmVyIH0gZnJvbSBcIi4vbWVtYmVyLWRlY2xhcmF0aW9uLXV0aWxpdGllc1wiO1xuXG5pbXBvcnQgeyBleHByZXNzaW9uUmVmZXJlbmNlc1N5bWJvbCB9IGZyb20gXCIuL21lbWJlci11c2FnZS1leHByZXNzaW9uLXJlZmVyZW5jZS11dGlsaXRpZXNcIjtcbmltcG9ydCB7IGlzRGVjbGFyYXRpb25Pbmx5TWV0aG9kIH0gZnJvbSBcIi4vbWVtYmVyLXVzYWdlLXR5cGUtdXRpbGl0aWVzXCI7XG5pbXBvcnQgeyBleHByZXNzaW9uQ2Fycmllc01lbWJlclZhbHVlIH0gZnJvbSBcIi4vbWVtYmVyLXVzYWdlLXZhbHVlLXV0aWxpdGllc1wiO1xuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIGEgbG9jYWwgY2FsbCBmb3J3YXJkcyBhIG1lbWJlci1iZWFyaW5nIHZhbHVlIHRvIGFuIEhUVFAgYm9keS5cbiAqIEBwYXJhbSBub2RlIENhbmRpZGF0ZSBsb2NhbCBjYWxsIGV4cHJlc3Npb24uXG4gKiBAcGFyYW0gY2hlY2tlciBUeXBlU2NyaXB0IHR5cGUgY2hlY2tlci5cbiAqIEBwYXJhbSBtZW1iZXIgTWVtYmVyIHdob3NlIHZhbHVlIGlzIGJlaW5nIHRyYW5zbWl0dGVkLlxuICogQHJldHVybnMgVHJ1ZSB3aGVuIHRoZSBhcmd1bWVudCByZWFjaGVzIGFuIG9wYXF1ZSByZXF1ZXN0IGJvZHkgY29udHJhY3QuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgdHJhbnNtaXR0ZWQgPSBpc0xvY2FsQ2FsbEFyZ3VtZW50VHJhbnNtaXR0ZWQoY2FsbCwgY2hlY2tlciwgbWVtYmVyKTtcbiAqIGBgYFxuICovXG5jb25zdCBpc0xvY2FsQ2FsbEFyZ3VtZW50VHJhbnNtaXR0ZWQgPSAoXG4gIG5vZGU6IHRzLk5vZGUsXG4gIGNoZWNrZXI6IHRzLlR5cGVDaGVja2VyLFxuICBtZW1iZXI6IFB1YmxpY01lbWJlcixcbik6IGJvb2xlYW4gPT4ge1xuICBpZiAoIXRzLmlzQ2FsbEV4cHJlc3Npb24obm9kZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBkZWNsYXJhdGlvbiA9IGNoZWNrZXIuZ2V0UmVzb2x2ZWRTaWduYXR1cmUobm9kZSk/LmdldERlY2xhcmF0aW9uKCk7XG4gIGlmICghaGFzRnVuY3Rpb25Cb2R5KGRlY2xhcmF0aW9uKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiBub2RlLmFyZ3VtZW50cy5zb21lKChhcmd1bWVudCwgYXJndW1lbnRJbmRleCkgPT4ge1xuICAgIGNvbnN0IHBhcmFtZXRlciA9XG4gICAgICBkZWNsYXJhdGlvbi5wYXJhbWV0ZXJzW1xuICAgICAgICBNYXRoLm1pbihhcmd1bWVudEluZGV4LCBkZWNsYXJhdGlvbi5wYXJhbWV0ZXJzLmxlbmd0aCAtIDEpXG4gICAgICBdO1xuICAgIGNvbnN0IHBhcmFtZXRlclN5bWJvbCA9XG4gICAgICBwYXJhbWV0ZXIgPT09IHZvaWQgMCB8fCAhdHMuaXNJZGVudGlmaWVyKHBhcmFtZXRlci5uYW1lKVxuICAgICAgICA/IHZvaWQgMFxuICAgICAgICA6IGNoZWNrZXIuZ2V0U3ltYm9sQXRMb2NhdGlvbihwYXJhbWV0ZXIubmFtZSk7XG5cbiAgICBjb25zdCBjYXJyaWVzID0gZXhwcmVzc2lvbkNhcnJpZXNNZW1iZXJWYWx1ZShhcmd1bWVudCwgY2hlY2tlciwgbWVtYmVyKTtcbiAgICBjb25zdCByZWFjaGVzQm9keSA9XG4gICAgICBwYXJhbWV0ZXJTeW1ib2wgIT09IHZvaWQgMCAmJlxuICAgICAgbG9jYWxQYXJhbWV0ZXJSZWFjaGVzUmVxdWVzdEJvZHkoXG4gICAgICAgIGRlY2xhcmF0aW9uLFxuICAgICAgICBwYXJhbWV0ZXJTeW1ib2wsXG4gICAgICAgIGNoZWNrZXIsXG4gICAgICAgIG5ldyBNYXAoKSxcbiAgICAgICk7XG4gICAgcmV0dXJuIHBhcmFtZXRlclN5bWJvbCAhPT0gdm9pZCAwICYmIGNhcnJpZXMgJiYgcmVhY2hlc0JvZHk7XG4gIH0pO1xufTtcblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBhIGxvY2FsIHBhcmFtZXRlciByZWFjaGVzIGEgZGVjbGFyZWQgSFRUUCByZXF1ZXN0IGJvZHkuXG4gKiBAcGFyYW0gZGVjbGFyYXRpb24gTG9jYWwgZnVuY3Rpb24gY29udGFpbmluZyB0aGUgcGFyYW1ldGVyLlxuICogQHBhcmFtIHBhcmFtZXRlclN5bWJvbCBQYXJhbWV0ZXIgc3ltYm9sIHdob3NlIHZhbHVlIGlzIHRyYWNlZC5cbiAqIEBwYXJhbSBjaGVja2VyIFR5cGVTY3JpcHQgdHlwZSBjaGVja2VyLlxuICogQHBhcmFtIHZpc2l0ZWREZWNsYXJhdGlvbnMgRnVuY3Rpb24gZGVjbGFyYXRpb25zIGFscmVhZHkgaW5zcGVjdGVkLlxuICogQHJldHVybnMgVHJ1ZSB3aGVuIHRoZSBwYXJhbWV0ZXIgcmVhY2hlcyBhbiBvcGFxdWUgcmVxdWVzdCBib2R5LlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHJlYWNoZXNCb2R5ID0gbG9jYWxQYXJhbWV0ZXJSZWFjaGVzUmVxdWVzdEJvZHkoXG4gKiAgIGRlY2xhcmF0aW9uLFxuICogICBwYXJhbWV0ZXJTeW1ib2wsXG4gKiAgIGNoZWNrZXIsXG4gKiAgIG5ldyBTZXQoKSxcbiAqICk7XG4gKiBgYGBcbiAqL1xuY29uc3QgbG9jYWxQYXJhbWV0ZXJSZWFjaGVzUmVxdWVzdEJvZHkgPSAoXG4gIGRlY2xhcmF0aW9uOiB0cy5TaWduYXR1cmVEZWNsYXJhdGlvbixcbiAgcGFyYW1ldGVyU3ltYm9sOiB0cy5TeW1ib2wsXG4gIGNoZWNrZXI6IHRzLlR5cGVDaGVja2VyLFxuICB2aXNpdGVkRGVjbGFyYXRpb25zOiBNYXA8dHMuU2lnbmF0dXJlRGVjbGFyYXRpb24sIFNldDx0cy5TeW1ib2w+Pixcbik6IGJvb2xlYW4gPT4ge1xuICBpZiAoIWhhc0Z1bmN0aW9uQm9keShkZWNsYXJhdGlvbikpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCB2aXNpdGVkUGFyYW1ldGVycyA9XG4gICAgdmlzaXRlZERlY2xhcmF0aW9ucy5nZXQoZGVjbGFyYXRpb24pID8/IG5ldyBTZXQ8dHMuU3ltYm9sPigpO1xuICBpZiAodmlzaXRlZFBhcmFtZXRlcnMuaGFzKHBhcmFtZXRlclN5bWJvbCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmlzaXRlZFBhcmFtZXRlcnMuYWRkKHBhcmFtZXRlclN5bWJvbCk7XG4gIHZpc2l0ZWREZWNsYXJhdGlvbnMuc2V0KGRlY2xhcmF0aW9uLCB2aXNpdGVkUGFyYW1ldGVycyk7XG5cbiAgY29uc3QgaW5zcGVjdCA9IChub2RlOiB0cy5Ob2RlKTogdHJ1ZSB8IHVuZGVmaW5lZCA9PiB7XG4gICAgaWYgKHRzLmlzQ2FsbEV4cHJlc3Npb24obm9kZSkpIHtcbiAgICAgIGNvbnN0IGlzQm9keSA9IGlzT3BhcXVlUmVxdWVzdEJvZHlIYW5kb2ZmKG5vZGUsIHBhcmFtZXRlclN5bWJvbCwgY2hlY2tlcik7XG4gICAgICBpZiAoaXNCb2R5KSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBuZXN0ZWREZWNsYXJhdGlvbiA9IGNoZWNrZXJcbiAgICAgICAgLmdldFJlc29sdmVkU2lnbmF0dXJlKG5vZGUpXG4gICAgICAgID8uZ2V0RGVjbGFyYXRpb24oKTtcbiAgICAgIGlmIChoYXNGdW5jdGlvbkJvZHkobmVzdGVkRGVjbGFyYXRpb24pKSB7XG4gICAgICAgIGZvciAoY29uc3QgW2FyZ3VtZW50SW5kZXgsIGFyZ3VtZW50XSBvZiBub2RlLmFyZ3VtZW50cy5lbnRyaWVzKCkpIHtcbiAgICAgICAgICBjb25zdCByZWZlcmVuY2VzID0gZXhwcmVzc2lvblJlZmVyZW5jZXNTeW1ib2woXG4gICAgICAgICAgICBhcmd1bWVudCxcbiAgICAgICAgICAgIHBhcmFtZXRlclN5bWJvbCxcbiAgICAgICAgICAgIGNoZWNrZXIsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAoIXJlZmVyZW5jZXMpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IG5lc3RlZFBhcmFtZXRlciA9XG4gICAgICAgICAgICBuZXN0ZWREZWNsYXJhdGlvbi5wYXJhbWV0ZXJzW1xuICAgICAgICAgICAgICBNYXRoLm1pbihhcmd1bWVudEluZGV4LCBuZXN0ZWREZWNsYXJhdGlvbi5wYXJhbWV0ZXJzLmxlbmd0aCAtIDEpXG4gICAgICAgICAgICBdO1xuICAgICAgICAgIGNvbnN0IG5lc3RlZFBhcmFtZXRlclN5bWJvbCA9XG4gICAgICAgICAgICBuZXN0ZWRQYXJhbWV0ZXIgPT09IHZvaWQgMCB8fCAhdHMuaXNJZGVudGlmaWVyKG5lc3RlZFBhcmFtZXRlci5uYW1lKVxuICAgICAgICAgICAgICA/IHZvaWQgMFxuICAgICAgICAgICAgICA6IGNoZWNrZXIuZ2V0U3ltYm9sQXRMb2NhdGlvbihuZXN0ZWRQYXJhbWV0ZXIubmFtZSk7XG5cbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBuZXN0ZWRQYXJhbWV0ZXJTeW1ib2wgIT09IHZvaWQgMCAmJlxuICAgICAgICAgICAgbG9jYWxQYXJhbWV0ZXJSZWFjaGVzUmVxdWVzdEJvZHkoXG4gICAgICAgICAgICAgIG5lc3RlZERlY2xhcmF0aW9uLFxuICAgICAgICAgICAgICBuZXN0ZWRQYXJhbWV0ZXJTeW1ib2wsXG4gICAgICAgICAgICAgIGNoZWNrZXIsXG4gICAgICAgICAgICAgIHZpc2l0ZWREZWNsYXJhdGlvbnMsXG4gICAgICAgICAgICApXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHMuZm9yRWFjaENoaWxkKG5vZGUsIGluc3BlY3QpO1xuICB9O1xuXG4gIHJldHVybiBpbnNwZWN0KGRlY2xhcmF0aW9uLmJvZHkpID09PSB0cnVlO1xufTtcblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBhIHJlcXVlc3QgY2FsbCBzZW5kcyB0aGUgdHJhY2VkIHBhcmFtZXRlciBhcyBvcGFxdWUgYm9keSBkYXRhLlxuICogQHBhcmFtIGNhbGwgQ2FuZGlkYXRlIGNhbGwgZXhwcmVzc2lvbi5cbiAqIEBwYXJhbSBwYXJhbWV0ZXJTeW1ib2wgUGFyYW1ldGVyIHN5bWJvbCB3aG9zZSB2YWx1ZSBpcyB0cmFjZWQuXG4gKiBAcGFyYW0gY2hlY2tlciBUeXBlU2NyaXB0IHR5cGUgY2hlY2tlci5cbiAqIEByZXR1cm5zIFRydWUgd2hlbiBhIGRlY2xhcmF0aW9uLW9ubHkgcmVxdWVzdCBtZXRob2QgYWNjZXB0cyB0aGUgdmFsdWUgYXMgYm9keS5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBvcGFxdWUgPSBpc09wYXF1ZVJlcXVlc3RCb2R5SGFuZG9mZihjYWxsLCBwYXJhbWV0ZXJTeW1ib2wsIGNoZWNrZXIpO1xuICogYGBgXG4gKi9cbmNvbnN0IGlzT3BhcXVlUmVxdWVzdEJvZHlIYW5kb2ZmID0gKFxuICBjYWxsOiB0cy5DYWxsRXhwcmVzc2lvbixcbiAgcGFyYW1ldGVyU3ltYm9sOiB0cy5TeW1ib2wsXG4gIGNoZWNrZXI6IHRzLlR5cGVDaGVja2VyLFxuKTogYm9vbGVhbiA9PiB7XG4gIGNvbnN0IGRlY2xhcmF0aW9uID0gY2hlY2tlci5nZXRSZXNvbHZlZFNpZ25hdHVyZShjYWxsKT8uZ2V0RGVjbGFyYXRpb24oKTtcblxuICBpZiAoXG4gICAgZGVjbGFyYXRpb24gPT09IHZvaWQgMCB8fFxuICAgICFpc0RlY2xhcmF0aW9uT25seU1ldGhvZChkZWNsYXJhdGlvbikgfHxcbiAgICAhdHMuaXNQcm9wZXJ0eUFjY2Vzc0V4cHJlc3Npb24oY2FsbC5leHByZXNzaW9uKSB8fFxuICAgIGNhbGwuZXhwcmVzc2lvbi5uYW1lLnRleHQgIT09IFwicmVxdWVzdFwiXG4gICkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiBjYWxsLmFyZ3VtZW50cy5zb21lKChhcmd1bWVudCkgPT4ge1xuICAgIGlmICghdHMuaXNPYmplY3RMaXRlcmFsRXhwcmVzc2lvbihhcmd1bWVudCkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBjb25zdCBvcHRpb25zVHlwZSA9IGNoZWNrZXIuZ2V0Q29udGV4dHVhbFR5cGUoYXJndW1lbnQpO1xuICAgIGNvbnN0IHJlcXVlc3RPcHRpb25zVHlwZSA9XG4gICAgICBvcHRpb25zVHlwZSA9PT0gdm9pZCAwID8gdm9pZCAwIDogY2hlY2tlci5nZXROb25OdWxsYWJsZVR5cGUob3B0aW9uc1R5cGUpO1xuICAgIGNvbnN0IGJvZHlQcm9wZXJ0eSA9XG4gICAgICByZXF1ZXN0T3B0aW9uc1R5cGUgPT09IHZvaWQgMFxuICAgICAgICA/IHZvaWQgMFxuICAgICAgICA6IGNoZWNrZXIuZ2V0UHJvcGVydHlPZlR5cGUocmVxdWVzdE9wdGlvbnNUeXBlLCBcImJvZHlcIik7XG4gICAgaWYgKGJvZHlQcm9wZXJ0eSA9PT0gdm9pZCAwKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgY29uc3QgYm9keVR5cGUgPSBjaGVja2VyLmdldFR5cGVPZlN5bWJvbEF0TG9jYXRpb24oYm9keVByb3BlcnR5LCBhcmd1bWVudCk7XG4gICAgaWYgKChib2R5VHlwZS5mbGFncyAmICh0cy5UeXBlRmxhZ3MuQW55IHwgdHMuVHlwZUZsYWdzLlVua25vd24pKSA9PT0gMCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiBhcmd1bWVudC5wcm9wZXJ0aWVzLnNvbWUoKHByb3BlcnR5KSA9PiB7XG4gICAgICByZXR1cm4gdHMuaXNQcm9wZXJ0eUFzc2lnbm1lbnQocHJvcGVydHkpICYmXG4gICAgICAgIHRzLmlzSWRlbnRpZmllcihwcm9wZXJ0eS5uYW1lKSAmJlxuICAgICAgICBwcm9wZXJ0eS5uYW1lLnRleHQgPT09IFwiYm9keVwiXG4gICAgICAgID8gZXhwcmVzc2lvblJlZmVyZW5jZXNTeW1ib2woXG4gICAgICAgICAgICBwcm9wZXJ0eS5pbml0aWFsaXplcixcbiAgICAgICAgICAgIHBhcmFtZXRlclN5bWJvbCxcbiAgICAgICAgICAgIGNoZWNrZXIsXG4gICAgICAgICAgKVxuICAgICAgICA6IHRzLmlzU2hvcnRoYW5kUHJvcGVydHlBc3NpZ25tZW50KHByb3BlcnR5KSAmJlxuICAgICAgICAgICAgcHJvcGVydHkubmFtZS50ZXh0ID09PSBcImJvZHlcIiAmJlxuICAgICAgICAgICAgZXhwcmVzc2lvblJlZmVyZW5jZXNTeW1ib2wocHJvcGVydHkubmFtZSwgcGFyYW1ldGVyU3ltYm9sLCBjaGVja2VyKTtcbiAgICB9KTtcbiAgfSk7XG59O1xuXG4vKipcbiAqIE5hcnJvd3MgYSBmdW5jdGlvbi1saWtlIGRlY2xhcmF0aW9uIHRvIG9uZSB3aXRoIGEgYm9keS5cbiAqIEBwYXJhbSBkZWNsYXJhdGlvbiBDYW5kaWRhdGUgY2FsbCBzaWduYXR1cmUgZGVjbGFyYXRpb24uXG4gKiBAcmV0dXJucyBXaGV0aGVyIHRoZSBkZWNsYXJhdGlvbiBoYXMgYSBmdW5jdGlvbiBib2R5LlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGlmIChoYXNGdW5jdGlvbkJvZHkoZGVjbGFyYXRpb24pKSBpbnNwZWN0KGRlY2xhcmF0aW9uLmJvZHkpO1xuICogYGBgXG4gKi9cbmNvbnN0IGhhc0Z1bmN0aW9uQm9keSA9IChcbiAgZGVjbGFyYXRpb246IHRzLlNpZ25hdHVyZURlY2xhcmF0aW9uIHwgdW5kZWZpbmVkLFxuKTogZGVjbGFyYXRpb24gaXMgdHMuU2lnbmF0dXJlRGVjbGFyYXRpb24gJiB7IGJvZHk6IHRzLkNvbmNpc2VCb2R5IH0gPT5cbiAgZGVjbGFyYXRpb24gIT09IHZvaWQgMCAmJlxuICBcImJvZHlcIiBpbiBkZWNsYXJhdGlvbiAmJlxuICBkZWNsYXJhdGlvbi5ib2R5ICE9PSB2b2lkIDA7XG5cbmV4cG9ydCB7IGlzTG9jYWxDYWxsQXJndW1lbnRUcmFuc21pdHRlZCB9O1xuIl19
@@ -0,0 +1,29 @@
1
+ import * as ts from "typescript";
2
+ import type { PublicMember } from "./member-declaration-utilities.js";
3
+ /**
4
+ * Checks whether a property read uses a structurally related host shape.
5
+ * @param node Candidate read node.
6
+ * @param checker TypeScript type checker.
7
+ * @param member Member whose usage is being checked.
8
+ * @returns True when the read resolves through a structural contract.
9
+ * @example
10
+ * ```typescript
11
+ * const used = isStructuralPropertyRead(node, checker, member);
12
+ * ```
13
+ */
14
+ declare const isStructuralPropertyRead: (node: ts.Node, checker: ts.TypeChecker, member: PublicMember) => boolean;
15
+ /**
16
+ * Checks whether a computed property access resolves to a member symbol.
17
+ * @param node Candidate element access expression.
18
+ * @param checker TypeScript type checker.
19
+ * @param member Member whose usage is being checked.
20
+ * @param relatedSymbols Member and contract symbols accepted as usage.
21
+ * @returns True when a resolved key selects the member.
22
+ * @example
23
+ * ```typescript
24
+ * const used = isComputedMemberRead(node, checker, member, relatedSymbols);
25
+ * ```
26
+ */
27
+ declare const isComputedMemberRead: (node: ts.Node, checker: ts.TypeChecker, member: PublicMember, relatedSymbols: ts.Symbol[]) => boolean;
28
+ export { isComputedMemberRead, isStructuralPropertyRead };
29
+ //# sourceMappingURL=member-usage-reference-utilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"member-usage-reference-utilities.d.ts","sourceRoot":"","sources":["../../../../src/domain/architecture/no-unused-public-members/member-usage-reference-utilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AA+DnE;;;;;;;;;;GAUG;AACH,QAAA,MAAM,wBAAwB,GAC5B,MAAM,EAAE,CAAC,IAAI,EACb,SAAS,EAAE,CAAC,WAAW,EACvB,QAAQ,YAAY,KACnB,OAQF,CAAC;AAyBF;;;;;;;;;;;GAWG;AACH,QAAA,MAAM,oBAAoB,GACxB,MAAM,EAAE,CAAC,IAAI,EACb,SAAS,EAAE,CAAC,WAAW,EACvB,QAAQ,YAAY,EACpB,gBAAgB,EAAE,CAAC,MAAM,EAAE,KAC1B,OAuCF,CAAC;AAEF,OAAO,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,CAAC"}
@@ -0,0 +1,115 @@
1
+ import * as ts from "typescript";
2
+ import { isSameSymbol, resolveCanonicalSymbol, } from "../no-unused-exports/no-unused-exports-symbol-utilities.js";
3
+ import { hasCompatibleMemberShape } from "./member-usage-type-utilities.js";
4
+ /**
5
+ * Gets the source type and key for a property read or destructuring use.
6
+ * @param node Candidate member-name node.
7
+ * @param checker TypeScript type checker.
8
+ * @returns Access details when the node reads a property.
9
+ * @example
10
+ * ```typescript
11
+ * const access = getPropertyAccess(node, checker);
12
+ * ```
13
+ */
14
+ const getPropertyAccess = (node, checker) => {
15
+ const parent = node.parent;
16
+ if (ts.isPropertyAccessExpression(parent) && parent.name === node) {
17
+ return {
18
+ name: parent.name.text,
19
+ sourceType: checker.getTypeAtLocation(parent.expression),
20
+ };
21
+ }
22
+ if (ts.isBindingElement(parent) &&
23
+ (parent.name === node || parent.propertyName === node) &&
24
+ ts.isObjectBindingPattern(parent.parent)) {
25
+ const owner = parent.parent.parent;
26
+ const sourceType = ts.isVariableDeclaration(owner)
27
+ ? checker.getTypeAtLocation(owner.initializer ?? owner.name)
28
+ : ts.isParameter(owner)
29
+ ? checker.getTypeAtLocation(owner)
30
+ : void 0;
31
+ const nameNode = parent.propertyName ?? parent.name;
32
+ return sourceType === void 0
33
+ ? void 0
34
+ : ts.isIdentifier(nameNode) || ts.isStringLiteralLike(nameNode)
35
+ ? { name: nameNode.text, sourceType }
36
+ : void 0;
37
+ }
38
+ return void 0;
39
+ };
40
+ /**
41
+ * Checks whether a property read uses a structurally related host shape.
42
+ * @param node Candidate read node.
43
+ * @param checker TypeScript type checker.
44
+ * @param member Member whose usage is being checked.
45
+ * @returns True when the read resolves through a structural contract.
46
+ * @example
47
+ * ```typescript
48
+ * const used = isStructuralPropertyRead(node, checker, member);
49
+ * ```
50
+ */
51
+ const isStructuralPropertyRead = (node, checker, member) => {
52
+ const access = getPropertyAccess(node, checker);
53
+ return (access !== void 0 &&
54
+ access.name === member.memberName &&
55
+ hasCompatibleMemberShape(access.sourceType, member, checker));
56
+ };
57
+ /**
58
+ * Gets the literal string keys represented by a TypeScript key type.
59
+ * @param type Key type from an element access expression.
60
+ * @returns Literal keys represented by the type.
61
+ * @example
62
+ * ```typescript
63
+ * const keys = getStringLiteralKeys(keyType);
64
+ * ```
65
+ */
66
+ const getStringLiteralKeys = (type) => {
67
+ if (type.isUnionOrIntersection()) {
68
+ return type.types.flatMap((part) => getStringLiteralKeys(part));
69
+ }
70
+ if ((type.flags & ts.TypeFlags.StringLiteral) !== 0) {
71
+ return [type.value];
72
+ }
73
+ return (type.flags & ts.TypeFlags.NumberLiteral) === 0
74
+ ? []
75
+ : [type.value.toFixed(0)];
76
+ };
77
+ /**
78
+ * Checks whether a computed property access resolves to a member symbol.
79
+ * @param node Candidate element access expression.
80
+ * @param checker TypeScript type checker.
81
+ * @param member Member whose usage is being checked.
82
+ * @param relatedSymbols Member and contract symbols accepted as usage.
83
+ * @returns True when a resolved key selects the member.
84
+ * @example
85
+ * ```typescript
86
+ * const used = isComputedMemberRead(node, checker, member, relatedSymbols);
87
+ * ```
88
+ */
89
+ const isComputedMemberRead = (node, checker, member, relatedSymbols) => {
90
+ if (!ts.isElementAccessExpression(node)) {
91
+ return false;
92
+ }
93
+ const objectType = checker.getTypeAtLocation(node.expression);
94
+ const keyType = checker.getTypeAtLocation(node.argumentExpression);
95
+ if ((keyType.flags & ts.TypeFlags.String) !== 0 &&
96
+ ts.isVariableDeclaration(member.hostDeclaration) &&
97
+ member.hostSymbol !== void 0) {
98
+ const accessedSymbol = checker.getSymbolAtLocation(node.expression);
99
+ if (accessedSymbol !== void 0 &&
100
+ isSameSymbol(resolveCanonicalSymbol(accessedSymbol, checker), resolveCanonicalSymbol(member.hostSymbol, checker))) {
101
+ return true;
102
+ }
103
+ }
104
+ return getStringLiteralKeys(keyType).some((name) => {
105
+ if (name !== member.memberName) {
106
+ return false;
107
+ }
108
+ const property = checker.getPropertyOfType(objectType, name);
109
+ return (property !== void 0 &&
110
+ (relatedSymbols.some((symbol) => isSameSymbol(symbol, property)) ||
111
+ hasCompatibleMemberShape(objectType, member, checker)));
112
+ });
113
+ };
114
+ export { isComputedMemberRead, isStructuralPropertyRead };
115
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVtYmVyLXVzYWdlLXJlZmVyZW5jZS11dGlsaXRpZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvZG9tYWluL2FyY2hpdGVjdHVyZS9uby11bnVzZWQtcHVibGljLW1lbWJlcnMvbWVtYmVyLXVzYWdlLXJlZmVyZW5jZS11dGlsaXRpZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFJakMsT0FBTyxFQUNMLFlBQVksRUFDWixzQkFBc0IsR0FDdkIsTUFBTSx5REFBeUQsQ0FBQztBQUNqRSxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQVd6RTs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLGlCQUFpQixHQUFHLENBQ3hCLElBQWEsRUFDYixPQUF1QixFQUNZLEVBQUU7SUFDckMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztJQUUzQixJQUFJLEVBQUUsQ0FBQywwQkFBMEIsQ0FBQyxNQUFNLENBQUMsSUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLElBQUksRUFBRSxDQUFDO1FBQ2xFLE9BQU87WUFDTCxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJO1lBQ3RCLFVBQVUsRUFBRSxPQUFPLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQztTQUN6RCxDQUFDO0lBQ0osQ0FBQztJQUVELElBQ0UsRUFBRSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQztRQUMzQixDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssSUFBSSxJQUFJLE1BQU0sQ0FBQyxZQUFZLEtBQUssSUFBSSxDQUFDO1FBQ3RELEVBQUUsQ0FBQyxzQkFBc0IsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQ3hDLENBQUM7UUFDRCxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQztRQUNuQyxN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eXBlc2NyaXB0XCI7XG5cbmltcG9ydCB0eXBlIHsgUHVibGljTWVtYmVyIH0gZnJvbSBcIi4vbWVtYmVyLWRlY2xhcmF0aW9uLXV0aWxpdGllc1wiO1xuXG5pbXBvcnQge1xuICBpc1NhbWVTeW1ib2wsXG4gIHJlc29sdmVDYW5vbmljYWxTeW1ib2wsXG59IGZyb20gXCIuLi9uby11bnVzZWQtZXhwb3J0cy9uby11bnVzZWQtZXhwb3J0cy1zeW1ib2wtdXRpbGl0aWVzXCI7XG5pbXBvcnQgeyBoYXNDb21wYXRpYmxlTWVtYmVyU2hhcGUgfSBmcm9tIFwiLi9tZW1iZXItdXNhZ2UtdHlwZS11dGlsaXRpZXNcIjtcblxuLyoqIFNvdXJjZSB0eXBlIGFuZCBuYW1lIGZvciBhIHByb3BlcnR5IGFjY2VzcyBvciBkZXN0cnVjdHVyaW5nIHJlYWQuICovXG5pbnRlcmZhY2UgUHJvcGVydHlBY2Nlc3NEZXRhaWxzIHtcbiAgLyoqIFByb3BlcnR5IG5hbWUgc2VsZWN0ZWQgYnkgdGhlIGFjY2Vzcy4gKi9cbiAgbmFtZTogc3RyaW5nO1xuXG4gIC8qKiBUeXBlIG9mIHRoZSBvYmplY3Qgd2hvc2UgcHJvcGVydHkgaXMgcmVhZC4gKi9cbiAgc291cmNlVHlwZTogdHMuVHlwZTtcbn1cblxuLyoqXG4gKiBHZXRzIHRoZSBzb3VyY2UgdHlwZSBhbmQga2V5IGZvciBhIHByb3BlcnR5IHJlYWQgb3IgZGVzdHJ1Y3R1cmluZyB1c2UuXG4gKiBAcGFyYW0gbm9kZSBDYW5kaWRhdGUgbWVtYmVyLW5hbWUgbm9kZS5cbiAqIEBwYXJhbSBjaGVja2VyIFR5cGVTY3JpcHQgdHlwZSBjaGVja2VyLlxuICogQHJldHVybnMgQWNjZXNzIGRldGFpbHMgd2hlbiB0aGUgbm9kZSByZWFkcyBhIHByb3BlcnR5LlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IGFjY2VzcyA9IGdldFByb3BlcnR5QWNjZXNzKG5vZGUsIGNoZWNrZXIpO1xuICogYGBgXG4gKi9cbmNvbnN0IGdldFByb3BlcnR5QWNjZXNzID0gKFxuICBub2RlOiB0cy5Ob2RlLFxuICBjaGVja2VyOiB0cy5UeXBlQ2hlY2tlcixcbik6IFByb3BlcnR5QWNjZXNzRGV0YWlscyB8IHVuZGVmaW5lZCA9PiB7XG4gIGNvbnN0IHBhcmVudCA9IG5vZGUucGFyZW50O1xuXG4gIGlmICh0cy5pc1Byb3BlcnR5QWNjZXNzRXhwcmVzc2lvbihwYXJlbnQpICYmIHBhcmVudC5uYW1lID09PSBub2RlKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG5hbWU6IHBhcmVudC5uYW1lLnRleHQsXG4gICAgICBzb3VyY2VUeXBlOiBjaGVja2VyLmdldFR5cGVBdExvY2F0aW9uKHBhcmVudC5leHByZXNzaW9uKSxcbiAgICB9O1xuICB9XG5cbiAgaWYgKFxuICAgIHRzLmlzQmluZGluZ0VsZW1lbnQocGFyZW50KSAmJlxuICAgIChwYXJlbnQubmFtZSA9PT0gbm9kZSB8fCBwYXJlbnQucHJvcGVydHlOYW1lID09PSBub2RlKSAmJlxuICAgIHRzLmlzT2JqZWN0QmluZGluZ1BhdHRlcm4ocGFyZW50LnBhcmVudClcbiAgKSB7XG4gICAgY29uc3Qgb3duZXIgPSBwYXJlbnQucGFyZW50LnBhcmVudDtcbiAgICBjb25zdCBzb3VyY2VUeXBlID0gdHMuaXNWYXJpYWJsZURlY2xhcmF0aW9uKG93bmVyKVxuICAgICAgPyBjaGVja2VyLmdldFR5cGVBdExvY2F0aW9uKG93bmVyLmluaXRpYWxpemVyID8/IG93bmVyLm5hbWUpXG4gICAgICA6IHRzLmlzUGFyYW1ldGVyKG93bmVyKVxuICAgICAgICA/IGNoZWNrZXIuZ2V0VHlwZUF0TG9jYXRpb24ob3duZXIpXG4gICAgICAgIDogdm9pZCAwO1xuICAgIGNvbnN0IG5hbWVOb2RlID0gcGFyZW50LnByb3BlcnR5TmFtZSA/PyBwYXJlbnQubmFtZTtcblxuICAgIHJldHVybiBzb3VyY2VUeXBlID09PSB2b2lkIDBcbiAgICAgID8gdm9pZCAwXG4gICAgICA6IHRzLmlzSWRlbnRpZmllcihuYW1lTm9kZSkgfHwgdHMuaXNTdHJpbmdMaXRlcmFsTGlrZShuYW1lTm9kZSlcbiAgICAgICAgPyB7IG5hbWU6IG5hbWVOb2RlLnRleHQsIHNvdXJjZVR5cGUgfVxuICAgICAgICA6IHZvaWQgMDtcbiAgfVxuXG4gIHJldHVybiB2b2lkIDA7XG59O1xuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIGEgcHJvcGVydHkgcmVhZCB1c2VzIGEgc3RydWN0dXJhbGx5IHJlbGF0ZWQgaG9zdCBzaGFwZS5cbiAqIEBwYXJhbSBub2RlIENhbmRpZGF0ZSByZWFkIG5vZGUuXG4gKiBAcGFyYW0gY2hlY2tlciBUeXBlU2NyaXB0IHR5cGUgY2hlY2tlci5cbiAqIEBwYXJhbSBtZW1iZXIgTWVtYmVyIHdob3NlIHVzYWdlIGlzIGJlaW5nIGNoZWNrZWQuXG4gKiBAcmV0dXJucyBUcnVlIHdoZW4gdGhlIHJlYWQgcmVzb2x2ZXMgdGhyb3VnaCBhIHN0cnVjdHVyYWwgY29udHJhY3QuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgdXNlZCA9IGlzU3RydWN0dXJhbFByb3BlcnR5UmVhZChub2RlLCBjaGVja2VyLCBtZW1iZXIpO1xuICogYGBgXG4gKi9cbmNvbnN0IGlzU3RydWN0dXJhbFByb3BlcnR5UmVhZCA9IChcbiAgbm9kZTogdHMuTm9kZSxcbiAgY2hlY2tlcjogdHMuVHlwZUNoZWNrZXIsXG4gIG1lbWJlcjogUHVibGljTWVtYmVyLFxuKTogYm9vbGVhbiA9PiB7XG4gIGNvbnN0IGFjY2VzcyA9IGdldFByb3BlcnR5QWNjZXNzKG5vZGUsIGNoZWNrZXIpO1xuXG4gIHJldHVybiAoXG4gICAgYWNjZXNzICE9PSB2b2lkIDAgJiZcbiAgICBhY2Nlc3MubmFtZSA9PT0gbWVtYmVyLm1lbWJlck5hbWUgJiZcbiAgICBoYXNDb21wYXRpYmxlTWVtYmVyU2hhcGUoYWNjZXNzLnNvdXJjZVR5cGUsIG1lbWJlciwgY2hlY2tlcilcbiAgKTtcbn07XG5cbi8qKlxuICogR2V0cyB0aGUgbGl0ZXJhbCBzdHJpbmcga2V5cyByZXByZXNlbnRlZCBieSBhIFR5cGVTY3JpcHQga2V5IHR5cGUuXG4gKiBAcGFyYW0gdHlwZSBLZXkgdHlwZSBmcm9tIGFuIGVsZW1lbnQgYWNjZXNzIGV4cHJlc3Npb24uXG4gKiBAcmV0dXJucyBMaXRlcmFsIGtleXMgcmVwcmVzZW50ZWQgYnkgdGhlIHR5cGUuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3Qga2V5cyA9IGdldFN0cmluZ0xpdGVyYWxLZXlzKGtleVR5cGUpO1xuICogYGBgXG4gKi9cbmNvbnN0IGdldFN0cmluZ0xpdGVyYWxLZXlzID0gKHR5cGU6IHRzLlR5cGUpOiBzdHJpbmdbXSA9PiB7XG4gIGlmICh0eXBlLmlzVW5pb25PckludGVyc2VjdGlvbigpKSB7XG4gICAgcmV0dXJuIHR5cGUudHlwZXMuZmxhdE1hcCgocGFydCkgPT4gZ2V0U3RyaW5nTGl0ZXJhbEtleXMocGFydCkpO1xuICB9XG5cbiAgaWYgKCh0eXBlLmZsYWdzICYgdHMuVHlwZUZsYWdzLlN0cmluZ0xpdGVyYWwpICE9PSAwKSB7XG4gICAgcmV0dXJuIFsodHlwZSBhcyB0cy5TdHJpbmdMaXRlcmFsVHlwZSkudmFsdWVdO1xuICB9XG5cbiAgcmV0dXJuICh0eXBlLmZsYWdzICYgdHMuVHlwZUZsYWdzLk51bWJlckxpdGVyYWwpID09PSAwXG4gICAgPyBbXVxuICAgIDogWyh0eXBlIGFzIHRzLk51bWJlckxpdGVyYWxUeXBlKS52YWx1ZS50b0ZpeGVkKDApXTtcbn07XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgYSBjb21wdXRlZCBwcm9wZXJ0eSBhY2Nlc3MgcmVzb2x2ZXMgdG8gYSBtZW1iZXIgc3ltYm9sLlxuICogQHBhcmFtIG5vZGUgQ2FuZGlkYXRlIGVsZW1lbnQgYWNjZXNzIGV4cHJlc3Npb24uXG4gKiBAcGFyYW0gY2hlY2tlciBUeXBlU2NyaXB0IHR5cGUgY2hlY2tlci5cbiAqIEBwYXJhbSBtZW1iZXIgTWVtYmVyIHdob3NlIHVzYWdlIGlzIGJlaW5nIGNoZWNrZWQuXG4gKiBAcGFyYW0gcmVsYXRlZFN5bWJvbHMgTWVtYmVyIGFuZCBjb250cmFjdCBzeW1ib2xzIGFjY2VwdGVkIGFzIHVzYWdlLlxuICogQHJldHVybnMgVHJ1ZSB3aGVuIGEgcmVzb2x2ZWQga2V5IHNlbGVjdHMgdGhlIG1lbWJlci5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCB1c2VkID0gaXNDb21wdXRlZE1lbWJlclJlYWQobm9kZSwgY2hlY2tlciwgbWVtYmVyLCByZWxhdGVkU3ltYm9scyk7XG4gKiBgYGBcbiAqL1xuY29uc3QgaXNDb21wdXRlZE1lbWJlclJlYWQgPSAoXG4gIG5vZGU6IHRzLk5vZGUsXG4gIGNoZWNrZXI6IHRzLlR5cGVDaGVja2VyLFxuICBtZW1iZXI6IFB1YmxpY01lbWJlcixcbiAgcmVsYXRlZFN5bWJvbHM6IHRzLlN5bWJvbFtdLFxuKTogYm9vbGVhbiA9PiB7XG4gIGlmICghdHMuaXNFbGVtZW50QWNjZXNzRXhwcmVzc2lvbihub2RlKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGNvbnN0IG9iamVjdFR5cGUgPSBjaGVja2VyLmdldFR5cGVBdExvY2F0aW9uKG5vZGUuZXhwcmVzc2lvbik7XG4gIGNvbnN0IGtleVR5cGUgPSBjaGVja2VyLmdldFR5cGVBdExvY2F0aW9uKG5vZGUuYXJndW1lbnRFeHByZXNzaW9uKTtcblxuICBpZiAoXG4gICAgKGtleVR5cGUuZmxhZ3MgJiB0cy5UeXBlRmxhZ3MuU3RyaW5nKSAhPT0gMCAmJlxuICAgIHRzLmlzVmFyaWFibGVEZWNsYXJhdGlvbihtZW1iZXIuaG9zdERlY2xhcmF0aW9uKSAmJlxuICAgIG1lbWJlci5ob3N0U3ltYm9sICE9PSB2b2lkIDBcbiAgKSB7XG4gICAgY29uc3QgYWNjZXNzZWRTeW1ib2wgPSBjaGVja2VyLmdldFN5bWJvbEF0TG9jYXRpb24obm9kZS5leHByZXNzaW9uKTtcblxuICAgIGlmIChcbiAgICAgIGFjY2Vzc2VkU3ltYm9sICE9PSB2b2lkIDAgJiZcbiAgICAgIGlzU2FtZVN5bWJvbChcbiAgICAgICAgcmVzb2x2ZUNhbm9uaWNhbFN5bWJvbChhY2Nlc3NlZFN5bWJvbCwgY2hlY2tlciksXG4gICAgICAgIHJlc29sdmVDYW5vbmljYWxTeW1ib2wobWVtYmVyLmhvc3RTeW1ib2wsIGNoZWNrZXIpLFxuICAgICAgKVxuICAgICkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGdldFN0cmluZ0xpdGVyYWxLZXlzKGtleVR5cGUpLnNvbWUoKG5hbWUpID0+IHtcbiAgICBpZiAobmFtZSAhPT0gbWVtYmVyLm1lbWJlck5hbWUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBjb25zdCBwcm9wZXJ0eSA9IGNoZWNrZXIuZ2V0UHJvcGVydHlPZlR5cGUob2JqZWN0VHlwZSwgbmFtZSk7XG5cbiAgICByZXR1cm4gKFxuICAgICAgcHJvcGVydHkgIT09IHZvaWQgMCAmJlxuICAgICAgKHJlbGF0ZWRTeW1ib2xzLnNvbWUoKHN5bWJvbCkgPT4gaXNTYW1lU3ltYm9sKHN5bWJvbCwgcHJvcGVydHkpKSB8fFxuICAgICAgICBoYXNDb21wYXRpYmxlTWVtYmVyU2hhcGUob2JqZWN0VHlwZSwgbWVtYmVyLCBjaGVja2VyKSlcbiAgICApO1xuICB9KTtcbn07XG5cbmV4cG9ydCB7IGlzQ29tcHV0ZWRNZW1iZXJSZWFkLCBpc1N0cnVjdHVyYWxQcm9wZXJ0eVJlYWQgfTtcbiJdfQ==
@@ -0,0 +1,30 @@
1
+ import * as ts from "typescript";
2
+ import type { PublicMember } from "./member-declaration-utilities.js";
3
+ /**
4
+ * Checks whether a local call serializes the value supplied to a parameter.
5
+ * @param node Candidate local call expression.
6
+ * @param checker TypeScript type checker.
7
+ * @param member Member whose value is being consumed.
8
+ * @param program TypeScript project program.
9
+ * @returns True when the argument is traced into standard JSON serialization.
10
+ * @example
11
+ * ```typescript
12
+ * const used = isLocalCallArgumentSerialized(node, checker, member, program);
13
+ * ```
14
+ */
15
+ declare const isLocalCallArgumentSerialized: (node: ts.Node, checker: ts.TypeChecker, member: PublicMember, program: ts.Program) => boolean;
16
+ /**
17
+ * Checks whether an operation copies or serializes a member-bearing value.
18
+ * @param node Candidate spread or call expression.
19
+ * @param checker TypeScript type checker.
20
+ * @param member Member whose value is being consumed.
21
+ * @param program TypeScript program used to identify standard library declarations.
22
+ * @returns True when the operation consumes the object's own properties.
23
+ * @example
24
+ * ```typescript
25
+ * const used = isWholeObjectRead(node, checker, member, program);
26
+ * ```
27
+ */
28
+ declare const isWholeObjectRead: (node: ts.Node, checker: ts.TypeChecker, member: PublicMember, program: ts.Program) => boolean;
29
+ export { isLocalCallArgumentSerialized, isWholeObjectRead };
30
+ //# sourceMappingURL=member-usage-serialization-utilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"member-usage-serialization-utilities.d.ts","sourceRoot":"","sources":["../../../../src/domain/architecture/no-unused-public-members/member-usage-serialization-utilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AASnE;;;;;;;;;;;GAWG;AACH,QAAA,MAAM,6BAA6B,GACjC,MAAM,EAAE,CAAC,IAAI,EACb,SAAS,EAAE,CAAC,WAAW,EACvB,QAAQ,YAAY,EACpB,SAAS,EAAE,CAAC,OAAO,KAClB,OAsDF,CAAC;AAmCF;;;;;;;;;;;GAWG;AACH,QAAA,MAAM,iBAAiB,GACrB,MAAM,EAAE,CAAC,IAAI,EACb,SAAS,EAAE,CAAC,WAAW,EACvB,QAAQ,YAAY,EACpB,SAAS,EAAE,CAAC,OAAO,KAClB,OA8BF,CAAC;AAEF,OAAO,EAAE,6BAA6B,EAAE,iBAAiB,EAAE,CAAC"}