@codeperfect/eslint-plugin 3.0.0 → 3.1.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 (99) hide show
  1. package/dist/application/custom-rules.d.ts +3 -0
  2. package/dist/application/custom-rules.d.ts.map +1 -1
  3. package/dist/application/custom-rules.js +3 -2
  4. package/dist/application/index.d.ts +1 -1
  5. package/dist/application/index.d.ts.map +1 -1
  6. package/dist/application/index.js +2 -2
  7. package/dist/codeperfect-eslint-plugin-1.0.0.tgz +0 -0
  8. package/dist/domain/architecture/consistent-barrel-files/barrel-file-utilities.d.ts +0 -2
  9. package/dist/domain/architecture/consistent-barrel-files/barrel-file-utilities.d.ts.map +1 -1
  10. package/dist/domain/architecture/consistent-barrel-files/barrel-file-utilities.js +1 -2
  11. package/dist/domain/architecture/consistent-barrel-files/consistent-barrel-files-options.d.ts +0 -2
  12. package/dist/domain/architecture/consistent-barrel-files/consistent-barrel-files-options.d.ts.map +1 -1
  13. package/dist/domain/architecture/consistent-barrel-files/consistent-barrel-files-options.js +2 -10
  14. package/dist/domain/architecture/index.d.ts +1 -0
  15. package/dist/domain/architecture/index.d.ts.map +1 -1
  16. package/dist/domain/architecture/index.js +2 -1
  17. package/dist/domain/architecture/no-unused-public-members/index.d.ts +2 -0
  18. package/dist/domain/architecture/no-unused-public-members/index.d.ts.map +1 -0
  19. package/dist/domain/architecture/no-unused-public-members/index.js +2 -0
  20. package/dist/domain/architecture/no-unused-public-members/member-contract-utilities.d.ts +16 -0
  21. package/dist/domain/architecture/no-unused-public-members/member-contract-utilities.d.ts.map +1 -0
  22. package/dist/domain/architecture/no-unused-public-members/member-contract-utilities.js +102 -0
  23. package/dist/domain/architecture/no-unused-public-members/member-declaration-utilities.d.ts +34 -0
  24. package/dist/domain/architecture/no-unused-public-members/member-declaration-utilities.d.ts.map +1 -0
  25. package/dist/domain/architecture/no-unused-public-members/member-declaration-utilities.js +55 -0
  26. package/dist/domain/architecture/no-unused-public-members/member-host-utilities.d.ts +68 -0
  27. package/dist/domain/architecture/no-unused-public-members/member-host-utilities.d.ts.map +1 -0
  28. package/dist/domain/architecture/no-unused-public-members/member-host-utilities.js +195 -0
  29. package/dist/domain/architecture/no-unused-public-members/member-public-api-utilities.d.ts +30 -0
  30. package/dist/domain/architecture/no-unused-public-members/member-public-api-utilities.d.ts.map +1 -0
  31. package/dist/domain/architecture/no-unused-public-members/member-public-api-utilities.js +101 -0
  32. package/dist/domain/architecture/no-unused-public-members/member-usage-handoff-utilities.d.ts +28 -0
  33. package/dist/domain/architecture/no-unused-public-members/member-usage-handoff-utilities.d.ts.map +1 -0
  34. package/dist/domain/architecture/no-unused-public-members/member-usage-handoff-utilities.js +125 -0
  35. package/dist/domain/architecture/no-unused-public-members/member-usage-reference-utilities.d.ts +29 -0
  36. package/dist/domain/architecture/no-unused-public-members/member-usage-reference-utilities.d.ts.map +1 -0
  37. package/dist/domain/architecture/no-unused-public-members/member-usage-reference-utilities.js +108 -0
  38. package/dist/domain/architecture/no-unused-public-members/member-usage-type-utilities.d.ts +42 -0
  39. package/dist/domain/architecture/no-unused-public-members/member-usage-type-utilities.d.ts.map +1 -0
  40. package/dist/domain/architecture/no-unused-public-members/member-usage-type-utilities.js +96 -0
  41. package/dist/domain/architecture/no-unused-public-members/member-usage-utilities.d.ts +18 -0
  42. package/dist/domain/architecture/no-unused-public-members/member-usage-utilities.d.ts.map +1 -0
  43. package/dist/domain/architecture/no-unused-public-members/member-usage-utilities.js +128 -0
  44. package/dist/domain/architecture/no-unused-public-members/member-utilities.d.ts +41 -0
  45. package/dist/domain/architecture/no-unused-public-members/member-utilities.d.ts.map +1 -0
  46. package/dist/domain/architecture/no-unused-public-members/member-utilities.js +51 -0
  47. package/dist/domain/architecture/no-unused-public-members/rule.d.ts +5 -0
  48. package/dist/domain/architecture/no-unused-public-members/rule.d.ts.map +1 -0
  49. package/dist/domain/architecture/no-unused-public-members/rule.js +78 -0
  50. package/dist/domain/docs/no-interface-member-docs/comment-utilities.js +4 -4
  51. package/dist/domain/docs/no-interface-member-docs/parameter-tags.d.ts.map +1 -1
  52. package/dist/domain/docs/no-interface-member-docs/parameter-tags.js +2 -2
  53. package/dist/domain/docs/no-interface-member-docs/parameter-utilities.js +4 -4
  54. package/dist/domain/docs/no-interface-member-docs/rule.d.ts.map +1 -1
  55. package/dist/domain/docs/no-interface-member-docs/rule.js +2 -5
  56. package/dist/domain/docs/require-example-language/example-utilities.d.ts +1 -7
  57. package/dist/domain/docs/require-example-language/example-utilities.d.ts.map +1 -1
  58. package/dist/domain/docs/require-example-language/example-utilities.js +4 -6
  59. package/dist/domain/docs/require-example-language/examples.d.ts.map +1 -1
  60. package/dist/domain/docs/require-example-language/examples.js +2 -4
  61. package/dist/domain/docs/require-example-language/reporting.d.ts.map +1 -1
  62. package/dist/domain/docs/require-example-language/reporting.js +1 -4
  63. package/dist/domain/docs/require-example-language/types.d.ts +0 -2
  64. package/dist/domain/docs/require-example-language/types.d.ts.map +1 -1
  65. package/dist/domain/docs/require-example-language/types.js +1 -1
  66. package/dist/domain/index.d.ts +1 -1
  67. package/dist/domain/index.d.ts.map +1 -1
  68. package/dist/domain/index.js +2 -2
  69. package/dist/domain/testing/aaa/analyzer.analysis.d.ts.map +1 -1
  70. package/dist/domain/testing/aaa/analyzer.analysis.js +2 -7
  71. package/dist/domain/testing/aaa/analyzer.assertions.js +2 -2
  72. package/dist/domain/testing/aaa/analyzer.classification.js +2 -2
  73. package/dist/domain/testing/aaa/types.d.ts +0 -4
  74. package/dist/domain/testing/aaa/types.d.ts.map +1 -1
  75. package/dist/domain/testing/aaa/types.js +1 -1
  76. package/dist/domain/testing/enforce-aaa-phase-purity/pattern-identifiers.d.ts.map +1 -1
  77. package/dist/domain/testing/enforce-aaa-phase-purity/pattern-identifiers.js +2 -7
  78. package/dist/domain/testing/prefer-vi-mocked-import/match-bindings.d.ts.map +1 -1
  79. package/dist/domain/testing/prefer-vi-mocked-import/match-bindings.js +5 -9
  80. package/dist/domain/testing/prefer-vi-mocked-import/match-collisions.d.ts.map +1 -1
  81. package/dist/domain/testing/prefer-vi-mocked-import/match-collisions.js +2 -7
  82. package/dist/domain/testing/prefer-vi-mocked-import/match-declarations.d.ts.map +1 -1
  83. package/dist/domain/testing/prefer-vi-mocked-import/match-declarations.js +5 -5
  84. package/dist/domain/testing/prefer-vi-mocked-import/match-imports.d.ts.map +1 -1
  85. package/dist/domain/testing/prefer-vi-mocked-import/match-imports.js +13 -20
  86. package/dist/domain/testing/prefer-vi-mocked-import/types.d.ts +0 -2
  87. package/dist/domain/testing/prefer-vi-mocked-import/types.d.ts.map +1 -1
  88. package/dist/domain/testing/prefer-vi-mocked-import/types.js +1 -1
  89. package/dist/domain/testing/require-test-companion/require-test-companion-options.js +3 -3
  90. package/dist/domain/testing/require-test-companion/rule.js +2 -2
  91. package/dist/index.d.ts +1 -1
  92. package/dist/index.d.ts.map +1 -1
  93. package/dist/index.js +2 -2
  94. package/dist/infrastructure/codeperfect-plugin.d.ts +2 -0
  95. package/dist/infrastructure/codeperfect-plugin.d.ts.map +1 -1
  96. package/dist/infrastructure/codeperfect-plugin.js +3 -2
  97. package/dist/infrastructure/presets.d.ts.map +1 -1
  98. package/dist/infrastructure/presets.js +3 -1
  99. package/package.json +24 -24
@@ -0,0 +1,195 @@
1
+ import * as ts from "typescript";
2
+ /**
3
+ * Gets a static member name, excluding dynamic and private keys.
4
+ * @param name Candidate declaration name.
5
+ * @returns Static name or undefined when the key is dynamic or private.
6
+ * @example
7
+ * ```typescript
8
+ * const name = getStaticMemberName(ts.factory.createIdentifier("run"));
9
+ * ```
10
+ */
11
+ const getStaticMemberName = (name) => {
12
+ if (name === void 0 ||
13
+ ts.isPrivateIdentifier(name) ||
14
+ ts.isComputedPropertyName(name)) {
15
+ return void 0;
16
+ }
17
+ return ts.isIdentifier(name) ||
18
+ ts.isStringLiteralLike(name) ||
19
+ ts.isNumericLiteral(name)
20
+ ? name.text
21
+ : void 0;
22
+ };
23
+ /**
24
+ * Gets the local name used to identify a supported host.
25
+ * @param node Host declaration.
26
+ * @returns Host name or an anonymous marker.
27
+ * @example
28
+ * ```typescript
29
+ * const name = getHostName(classDeclaration);
30
+ * ```
31
+ */
32
+ const getHostName = (node) => {
33
+ if ((ts.isClassDeclaration(node) ||
34
+ ts.isInterfaceDeclaration(node) ||
35
+ ts.isTypeAliasDeclaration(node)) &&
36
+ node.name !== void 0) {
37
+ return node.name.text;
38
+ }
39
+ return ts.isVariableDeclaration(node) && ts.isIdentifier(node.name)
40
+ ? node.name.text
41
+ : "<anonymous>";
42
+ };
43
+ /**
44
+ * Resolves a direct object-literal property symbol before its contextual type.
45
+ * @param checker TypeScript type checker.
46
+ * @param member Member declaration.
47
+ * @param memberName Static member name.
48
+ * @param hostType Type of the containing host.
49
+ * @returns Member symbol when TypeScript can resolve it.
50
+ * @example
51
+ * ```typescript
52
+ * const symbol = getMemberSymbol(checker, property, "value", hostType);
53
+ * ```
54
+ */
55
+ const getMemberSymbol = (checker, member, memberName, hostType) => {
56
+ const nameNode = member.name;
57
+ const isObjectMember = ts.isPropertyAssignment(member) ||
58
+ ts.isShorthandPropertyAssignment(member) ||
59
+ ts.isMethodDeclaration(member) ||
60
+ ts.isGetAccessorDeclaration(member) ||
61
+ ts.isSetAccessorDeclaration(member);
62
+ if (isObjectMember && ts.isObjectLiteralExpression(member.parent)) {
63
+ const objectMember = checker.getPropertyOfType(checker.getTypeAtLocation(member.parent), memberName);
64
+ if (objectMember !== void 0) {
65
+ return objectMember;
66
+ }
67
+ }
68
+ const directSymbol = nameNode === void 0 ? void 0 : checker.getSymbolAtLocation(nameNode);
69
+ return directSymbol ?? checker.getPropertyOfType(hostType, memberName);
70
+ };
71
+ /**
72
+ * Unwraps supported expressions to find a direct object-literal initializer.
73
+ * @param expression Variable initializer.
74
+ * @returns Direct object literal or undefined.
75
+ * @example
76
+ * ```typescript
77
+ * const object = getObjectLiteral(variable.initializer);
78
+ * ```
79
+ */
80
+ const getObjectLiteral = (expression) => {
81
+ if (expression === void 0) {
82
+ return void 0;
83
+ }
84
+ if (ts.isObjectLiteralExpression(expression)) {
85
+ return expression;
86
+ }
87
+ return ts.isAsExpression(expression) ||
88
+ ts.isSatisfiesExpression(expression) ||
89
+ ts.isTypeAssertionExpression(expression) ||
90
+ ts.isParenthesizedExpression(expression) ||
91
+ ts.isNonNullExpression(expression)
92
+ ? getObjectLiteral(expression.expression)
93
+ : void 0;
94
+ };
95
+ /**
96
+ * Checks whether a class member is public or has implicit public visibility.
97
+ * @param member Class member declaration.
98
+ * @returns True when the member is not private or protected.
99
+ * @example
100
+ * ```typescript
101
+ * const visible = isPublicClassMember(classMethod);
102
+ * ```
103
+ */
104
+ const isPublicClassMember = (member) => {
105
+ const supportsVisibility = ts.isPropertyDeclaration(member) ||
106
+ ts.isMethodDeclaration(member) ||
107
+ ts.isGetAccessorDeclaration(member) ||
108
+ ts.isSetAccessorDeclaration(member);
109
+ if (!supportsVisibility) {
110
+ return false;
111
+ }
112
+ const modifiers = ts.canHaveModifiers(member)
113
+ ? (ts.getModifiers(member) ?? [])
114
+ : [];
115
+ return modifiers.every((modifier) => modifier.kind !== ts.SyntaxKind.PrivateKeyword &&
116
+ modifier.kind !== ts.SyntaxKind.ProtectedKeyword);
117
+ };
118
+ /**
119
+ * Checks whether a node is a supported direct property or method.
120
+ * @param member Candidate TypeScript member.
121
+ * @returns True when this rule analyzes the member kind.
122
+ * @example
123
+ * ```typescript
124
+ * const supported = isSupportedMember(typeMember);
125
+ * ```
126
+ */
127
+ const isSupportedMember = (member) => ts.isPropertyDeclaration(member) ||
128
+ ts.isMethodDeclaration(member) ||
129
+ ts.isGetAccessorDeclaration(member) ||
130
+ ts.isSetAccessorDeclaration(member) ||
131
+ ts.isPropertySignature(member) ||
132
+ ts.isMethodSignature(member) ||
133
+ ts.isPropertyAssignment(member) ||
134
+ ts.isShorthandPropertyAssignment(member);
135
+ /**
136
+ * Collects direct class, interface, type-alias, and const-object hosts.
137
+ * @param sourceFile Source file to inspect.
138
+ * @param checker TypeScript type checker.
139
+ * @returns Supported hosts declared by the source file.
140
+ * @example
141
+ * ```typescript
142
+ * const hosts = collectMemberHosts(sourceFile, checker);
143
+ * ```
144
+ */
145
+ const collectMemberHosts = (sourceFile, checker) => {
146
+ const hosts = [];
147
+ const visit = (node) => {
148
+ if (ts.isClassDeclaration(node)) {
149
+ hosts.push({
150
+ members: node.members,
151
+ name: getHostName(node),
152
+ node,
153
+ symbol: node.name === void 0
154
+ ? void 0
155
+ : checker.getSymbolAtLocation(node.name),
156
+ });
157
+ }
158
+ else if (ts.isInterfaceDeclaration(node)) {
159
+ hosts.push({
160
+ members: node.members,
161
+ name: getHostName(node),
162
+ node,
163
+ symbol: checker.getSymbolAtLocation(node.name),
164
+ });
165
+ }
166
+ else if (ts.isTypeAliasDeclaration(node) &&
167
+ ts.isTypeLiteralNode(node.type)) {
168
+ hosts.push({
169
+ members: node.type.members,
170
+ name: getHostName(node),
171
+ node,
172
+ symbol: checker.getSymbolAtLocation(node.name),
173
+ });
174
+ }
175
+ else if (ts.isVariableDeclaration(node) &&
176
+ ts.isIdentifier(node.name) &&
177
+ ts.isVariableDeclarationList(node.parent) &&
178
+ (node.parent.flags & ts.NodeFlags.Const) !== 0) {
179
+ const objectLiteral = getObjectLiteral(node.initializer);
180
+ if (objectLiteral !== void 0) {
181
+ hosts.push({
182
+ members: objectLiteral.properties,
183
+ name: getHostName(node),
184
+ node,
185
+ symbol: checker.getSymbolAtLocation(node.name),
186
+ });
187
+ }
188
+ }
189
+ ts.forEachChild(node, visit);
190
+ };
191
+ visit(sourceFile);
192
+ return hosts;
193
+ };
194
+ export { collectMemberHosts, getMemberSymbol, getStaticMemberName, isPublicClassMember, isSupportedMember, };
195
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVtYmVyLWhvc3QtdXRpbGl0aWVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2RvbWFpbi9hcmNoaXRlY3R1cmUvbm8tdW51c2VkLXB1YmxpYy1tZW1iZXJzL21lbWJlci1ob3N0LXV0aWxpdGllcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxNQUFNLFlBQVksQ0FBQztBQWlCakM7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLG1CQUFtQixHQUFHLENBQUMsSUFBeUIsRUFBc0IsRUFBRTtJQUM1RSxJQUNFLElBQUksS0FBSyxLQUFLLENBQUM7UUFDZixFQUFFLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDO1FBQzVCLEVBQUUsQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsRUFDL0IsQ0FBQztRQUNELE9BQU8sS0FBSyxDQUFDLENBQUM7SUFDaEIsQ0FBQztJQUVELE9BQU8sRUFBRSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUM7UUFDMUIsRUFBRSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQztRQUM1QixFQUFFLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDO1FBQ3pCLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSTtRQUNYLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUNiLENBQUMsQ0FBQztBQUVGOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxXQUFXLEdBQUcsQ0FBQyxJQUFhLEVBQVUsRUFBRTtJQUM1QyxJQUNFLENBQUMsRUFBRSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQztRQUMxQixFQUFFLENBQUMsc0JBQXNCLENBQUMsSUFBSSxDQUFDO1FBQy9CLEVBQUUsQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNsQyxJQUFJLENBQUMsSUFBSSxLQUFLLEtBQUssQ0FBQyxFQUNwQixDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FB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Q0FBQyx5QkFBeUIsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO1lBQ3pDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEVBQzlDLENBQUM7WUFDRCxNQUFNLGFBQWEsR0FBRyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7WUFFekQsSUFBSSxhQUFhLEtBQUssS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDN0IsS0FBSyxDQUFDLElBQUksQ0FBQztvQkFDVCxPQUFPLEVBQUUsYUFBYSxDQUFDLFVBQVU7b0JBQ2pDLElBQUksRUFBRSxXQUFXLENBQUMsSUFBSSxDQUFDO29CQUN2QixJQUFJO29CQUNKLE1BQU0sRUFBRSxPQUFPLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztpQkFDL0MsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztRQUNILENBQUM7UUFFRCxFQUFFLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztJQUMvQixDQUFDLENBQUM7SUFFRixLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7SUFFbEIsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDLENBQUM7QUFFRixPQUFPLEVBQ0wsa0JBQWtCLEVBQ2xCLGVBQWUsRUFDZixtQkFBbUIsRUFDbkIsbUJBQW1CLEVBQ25CLGlCQUFpQixHQUNsQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgdHMgZnJvbSBcInR5cGVzY3JpcHRcIjtcblxuLyoqIE9uZSBzdXBwb3J0ZWQgaG9zdCBhbmQgaXRzIGRpcmVjdCBtZW1iZXIgZGVjbGFyYXRpb25zLiAqL1xuaW50ZXJmYWNlIE1lbWJlckhvc3Qge1xuICAvKiogTWVtYmVycyBkZWNsYXJlZCBkaXJlY3RseSBieSB0aGlzIGhvc3QuICovXG4gIG1lbWJlcnM6IHJlYWRvbmx5IHRzLk5vZGVbXTtcblxuICAvKiogRGlzcGxheSBuYW1lIG9mIHRoZSBob3N0LiAqL1xuICBuYW1lOiBzdHJpbmc7XG5cbiAgLyoqIEhvc3QgZGVjbGFyYXRpb24gbm9kZS4gKi9cbiAgbm9kZTogdHMuTm9kZTtcblxuICAvKiogSG9zdCBzeW1ib2wsIHdoZW4gYXZhaWxhYmxlLiAqL1xuICBzeW1ib2w6IHRzLlN5bWJvbCB8IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBHZXRzIGEgc3RhdGljIG1lbWJlciBuYW1lLCBleGNsdWRpbmcgZHluYW1pYyBhbmQgcHJpdmF0ZSBrZXlzLlxuICogQHBhcmFtIG5hbWUgQ2FuZGlkYXRlIGRlY2xhcmF0aW9uIG5hbWUuXG4gKiBAcmV0dXJucyBTdGF0aWMgbmFtZSBvciB1bmRlZmluZWQgd2hlbiB0aGUga2V5IGlzIGR5bmFtaWMgb3IgcHJpdmF0ZS5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBuYW1lID0gZ2V0U3RhdGljTWVtYmVyTmFtZSh0cy5mYWN0b3J5LmNyZWF0ZUlkZW50aWZpZXIoXCJydW5cIikpO1xuICogYGBgXG4gKi9cbmNvbnN0IGdldFN0YXRpY01lbWJlck5hbWUgPSAobmFtZTogdHMuTm9kZSB8IHVuZGVmaW5lZCk6IHN0cmluZyB8IHVuZGVmaW5lZCA9PiB7XG4gIGlmIChcbiAgICBuYW1lID09PSB2b2lkIDAgfHxcbiAgICB0cy5pc1ByaXZhdGVJZGVudGlmaWVyKG5hbWUpIHx8XG4gICAgdHMuaXNDb21wdXRlZFByb3BlcnR5TmFtZShuYW1lKVxuICApIHtcbiAgICByZXR1cm4gdm9pZCAwO1xuICB9XG5cbiAgcmV0dXJuIHRzLmlzSWRlbnRpZmllcihuYW1lKSB8fFxuICAgIHRzLmlzU3RyaW5nTGl0ZXJhbExpa2UobmFtZSkgfHxcbiAgICB0cy5pc051bWVyaWNMaXRlcmFsKG5hbWUpXG4gICAgPyBuYW1lLnRleHRcbiAgICA6IHZvaWQgMDtcbn07XG5cbi8qKlxuICogR2V0cyB0aGUgbG9jYWwgbmFtZSB1c2VkIHRvIGlkZW50aWZ5IGEgc3VwcG9ydGVkIGhvc3QuXG4gKiBAcGFyYW0gbm9kZSBIb3N0IGRlY2xhcmF0aW9uLlxuICogQHJldHVybnMgSG9zdCBuYW1lIG9yIGFuIGFub255bW91cyBtYXJrZXIuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgbmFtZSA9IGdldEhvc3ROYW1lKGNsYXNzRGVjbGFyYXRpb24pO1xuICogYGBgXG4gKi9cbmNvbnN0IGdldEhvc3ROYW1lID0gKG5vZGU6IHRzLk5vZGUpOiBzdHJpbmcgPT4ge1xuICBpZiAoXG4gICAgKHRzLmlzQ2xhc3NEZWNsYXJhdGlvbihub2RlKSB8fFxuICAgICAgdHMuaXNJbnRlcmZhY2VEZWNsYXJhdGlvbihub2RlKSB8fFxuICAgICAgdHMuaXNUeXBlQWxpYXNEZWNsYXJhdGlvbihub2RlKSkgJiZcbiAgICBub2RlLm5hbWUgIT09IHZvaWQgMFxuICApIHtcbiAgICByZXR1cm4gbm9kZS5uYW1lLnRleHQ7XG4gIH1cblxuICByZXR1cm4gdHMuaXNWYXJpYWJsZURlY2xhcmF0aW9uKG5vZGUpICYmIHRzLmlzSWRlbnRpZmllcihub2RlLm5hbWUpXG4gICAgPyBub2RlLm5hbWUudGV4dFxuICAgIDogXCI8YW5vbnltb3VzPlwiO1xufTtcblxuLyoqXG4gKiBSZXNvbHZlcyBhIGRpcmVjdCBvYmplY3QtbGl0ZXJhbCBwcm9wZXJ0eSBzeW1ib2wgYmVmb3JlIGl0cyBjb250ZXh0dWFsIHR5cGUuXG4gKiBAcGFyYW0gY2hlY2tlciBUeXBlU2NyaXB0IHR5cGUgY2hlY2tlci5cbiAqIEBwYXJhbSBtZW1iZXIgTWVtYmVyIGRlY2xhcmF0aW9uLlxuICogQHBhcmFtIG1lbWJlck5hbWUgU3RhdGljIG1lbWJlciBuYW1lLlxuICogQHBhcmFtIGhvc3RUeXBlIFR5cGUgb2YgdGhlIGNvbnRhaW5pbmcgaG9zdC5cbiAqIEByZXR1cm5zIE1lbWJlciBzeW1ib2wgd2hlbiBUeXBlU2NyaXB0IGNhbiByZXNvbHZlIGl0LlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHN5bWJvbCA9IGdldE1lbWJlclN5bWJvbChjaGVja2VyLCBwcm9wZXJ0eSwgXCJ2YWx1ZVwiLCBob3N0VHlwZSk7XG4gKiBgYGBcbiAqL1xuY29uc3QgZ2V0TWVtYmVyU3ltYm9sID0gKFxuICBjaGVja2VyOiB0cy5UeXBlQ2hlY2tlcixcbiAgbWVtYmVyOiB0cy5Ob2RlLFxuICBtZW1iZXJOYW1lOiBzdHJpbmcsXG4gIGhvc3RUeXBlOiB0cy5UeXBlLFxuKTogdHMuU3ltYm9sIHwgdW5kZWZpbmVkID0+IHtcbiAgY29uc3QgbmFtZU5vZGUgPSAobWVtYmVyIGFzIHRzLk5hbWVkRGVjbGFyYXRpb24pLm5hbWU7XG4gIGNvbnN0IGlzT2JqZWN0TWVtYmVyID1cbiAgICB0cy5pc1Byb3BlcnR5QXNzaWdubWVudChtZW1iZXIpIHx8XG4gICAgdHMuaXNTaG9ydGhhbmRQcm9wZXJ0eUFzc2lnbm1lbnQobWVtYmVyKSB8fFxuICAgIHRzLmlzTWV0aG9kRGVjbGFyYXRpb24obWVtYmVyKSB8fFxuICAgIHRzLmlzR2V0QWNjZXNzb3JEZWNsYXJhdGlvbihtZW1iZXIpIHx8XG4gICAgdHMuaXNTZXRBY2Nlc3NvckRlY2xhcmF0aW9uKG1lbWJlcik7XG5cbiAgaWYgKGlzT2JqZWN0TWVtYmVyICYmIHRzLmlzT2JqZWN0TGl0ZXJhbEV4cHJlc3Npb24obWVtYmVyLnBhcmVudCkpIHtcbiAgICBjb25zdCBvYmplY3RNZW1iZXIgPSBjaGVja2VyLmdldFByb3BlcnR5T2ZUeXBlKFxuICAgICAgY2hlY2tlci5nZXRUeXBlQXRMb2NhdGlvbihtZW1iZXIucGFyZW50KSxcbiAgICAgIG1lbWJlck5hbWUsXG4gICAgKTtcblxuICAgIGlmIChvYmplY3RNZW1iZXIgIT09IHZvaWQgMCkge1xuICAgICAgcmV0dXJuIG9iamVjdE1lbWJlcjtcbiAgICB9XG4gIH1cblxuICBjb25zdCBkaXJlY3RTeW1ib2wgPVxuICAgIG5hbWVOb2RlID09PSB2b2lkIDAgPyB2b2lkIDAgOiBjaGVja2VyLmdldFN5bWJvbEF0TG9jYXRpb24obmFtZU5vZGUpO1xuXG4gIHJldHVybiBkaXJlY3RTeW1ib2wgPz8gY2hlY2tlci5nZXRQcm9wZXJ0eU9mVHlwZShob3N0VHlwZSwgbWVtYmVyTmFtZSk7XG59O1xuXG4vKipcbiAqIFVud3JhcHMgc3VwcG9ydGVkIGV4cHJlc3Npb25zIHRvIGZpbmQgYSBkaXJlY3Qgb2JqZWN0LWxpdGVyYWwgaW5pdGlhbGl6ZXIuXG4gKiBAcGFyYW0gZXhwcmVzc2lvbiBWYXJpYWJsZSBpbml0aWFsaXplci5cbiAqIEByZXR1cm5zIERpcmVjdCBvYmplY3QgbGl0ZXJhbCBvciB1bmRlZmluZWQuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3Qgb2JqZWN0ID0gZ2V0T2JqZWN0TGl0ZXJhbCh2YXJpYWJsZS5pbml0aWFsaXplcik7XG4gKiBgYGBcbiAqL1xuY29uc3QgZ2V0T2JqZWN0TGl0ZXJhbCA9IChcbiAgZXhwcmVzc2lvbjogdHMuRXhwcmVzc2lvbiB8IHVuZGVmaW5lZCxcbik6IHRzLk9iamVjdExpdGVyYWxFeHByZXNzaW9uIHwgdW5kZWZpbmVkID0+IHtcbiAgaWYgKGV4cHJlc3Npb24gPT09IHZvaWQgMCkge1xuICAgIHJldHVybiB2b2lkIDA7XG4gIH1cblxuICBpZiAodHMuaXNPYmplY3RMaXRlcmFsRXhwcmVzc2lvbihleHByZXNzaW9uKSkge1xuICAgIHJldHVybiBleHByZXNzaW9uO1xuICB9XG5cbiAgcmV0dXJuIHRzLmlzQXNFeHByZXNzaW9uKGV4cHJlc3Npb24pIHx8XG4gICAgdHMuaXNTYXRpc2ZpZXNFeHByZXNzaW9uKGV4cHJlc3Npb24pIHx8XG4gICAgdHMuaXNUeXBlQXNzZXJ0aW9uRXhwcmVzc2lvbihleHByZXNzaW9uKSB8fFxuICAgIHRzLmlzUGFyZW50aGVzaXplZEV4cHJlc3Npb24oZXhwcmVzc2lvbikgfHxcbiAgICB0cy5pc05vbk51bGxFeHByZXNzaW9uKGV4cHJlc3Npb24pXG4gICAgPyBnZXRPYmplY3RMaXRlcmFsKGV4cHJlc3Npb24uZXhwcmVzc2lvbilcbiAgICA6IHZvaWQgMDtcbn07XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgYSBjbGFzcyBtZW1iZXIgaXMgcHVibGljIG9yIGhhcyBpbXBsaWNpdCBwdWJsaWMgdmlzaWJpbGl0eS5cbiAqIEBwYXJhbSBtZW1iZXIgQ2xhc3MgbWVtYmVyIGRlY2xhcmF0aW9uLlxuICogQHJldHVybnMgVHJ1ZSB3aGVuIHRoZSBtZW1iZXIgaXMgbm90IHByaXZhdGUgb3IgcHJvdGVjdGVkLlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHZpc2libGUgPSBpc1B1YmxpY0NsYXNzTWVtYmVyKGNsYXNzTWV0aG9kKTtcbiAqIGBgYFxuICovXG5jb25zdCBpc1B1YmxpY0NsYXNzTWVtYmVyID0gKG1lbWJlcjogdHMuTm9kZSk6IGJvb2xlYW4gPT4ge1xuICBjb25zdCBzdXBwb3J0c1Zpc2liaWxpdHkgPVxuICAgIHRzLmlzUHJvcGVydHlEZWNsYXJhdGlvbihtZW1iZXIpIHx8XG4gICAgdHMuaXNNZXRob2REZWNsYXJhdGlvbihtZW1iZXIpIHx8XG4gICAgdHMuaXNHZXRBY2Nlc3NvckRlY2xhcmF0aW9uKG1lbWJlcikgfHxcbiAgICB0cy5pc1NldEFjY2Vzc29yRGVjbGFyYXRpb24obWVtYmVyKTtcblxuICBpZiAoIXN1cHBvcnRzVmlzaWJpbGl0eSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGNvbnN0IG1vZGlmaWVycyA9IHRzLmNhbkhhdmVNb2RpZmllcnMobWVtYmVyKVxuICAgID8gKHRzLmdldE1vZGlmaWVycyhtZW1iZXIpID8/IFtdKVxuICAgIDogW107XG5cbiAgcmV0dXJuIG1vZGlmaWVycy5ldmVyeShcbiAgICAobW9kaWZpZXIpID0+XG4gICAgICBtb2RpZmllci5raW5kICE9PSB0cy5TeW50YXhLaW5kLlByaXZhdGVLZXl3b3JkICYmXG4gICAgICBtb2RpZmllci5raW5kICE9PSB0cy5TeW50YXhLaW5kLlByb3RlY3RlZEtleXdvcmQsXG4gICk7XG59O1xuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIGEgbm9kZSBpcyBhIHN1cHBvcnRlZCBkaXJlY3QgcHJvcGVydHkgb3IgbWV0aG9kLlxuICogQHBhcmFtIG1lbWJlciBDYW5kaWRhdGUgVHlwZVNjcmlwdCBtZW1iZXIuXG4gKiBAcmV0dXJucyBUcnVlIHdoZW4gdGhpcyBydWxlIGFuYWx5emVzIHRoZSBtZW1iZXIga2luZC5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBzdXBwb3J0ZWQgPSBpc1N1cHBvcnRlZE1lbWJlcih0eXBlTWVtYmVyKTtcbiAqIGBgYFxuICovXG5jb25zdCBpc1N1cHBvcnRlZE1lbWJlciA9IChtZW1iZXI6IHRzLk5vZGUpOiBib29sZWFuID0+XG4gIHRzLmlzUHJvcGVydHlEZWNsYXJhdGlvbihtZW1iZXIpIHx8XG4gIHRzLmlzTWV0aG9kRGVjbGFyYXRpb24obWVtYmVyKSB8fFxuICB0cy5pc0dldEFjY2Vzc29yRGVjbGFyYXRpb24obWVtYmVyKSB8fFxuICB0cy5pc1NldEFjY2Vzc29yRGVjbGFyYXRpb24obWVtYmVyKSB8fFxuICB0cy5pc1Byb3BlcnR5U2lnbmF0dXJlKG1lbWJlcikgfHxcbiAgdHMuaXNNZXRob2RTaWduYXR1cmUobWVtYmVyKSB8fFxuICB0cy5pc1Byb3BlcnR5QXNzaWdubWVudChtZW1iZXIpIHx8XG4gIHRzLmlzU2hvcnRoYW5kUHJvcGVydHlBc3NpZ25tZW50KG1lbWJlcik7XG5cbi8qKlxuICogQ29sbGVjdHMgZGlyZWN0IGNsYXNzLCBpbnRlcmZhY2UsIHR5cGUtYWxpYXMsIGFuZCBjb25zdC1vYmplY3QgaG9zdHMuXG4gKiBAcGFyYW0gc291cmNlRmlsZSBTb3VyY2UgZmlsZSB0byBpbnNwZWN0LlxuICogQHBhcmFtIGNoZWNrZXIgVHlwZVNjcmlwdCB0eXBlIGNoZWNrZXIuXG4gKiBAcmV0dXJucyBTdXBwb3J0ZWQgaG9zdHMgZGVjbGFyZWQgYnkgdGhlIHNvdXJjZSBmaWxlLlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IGhvc3RzID0gY29sbGVjdE1lbWJlckhvc3RzKHNvdXJjZUZpbGUsIGNoZWNrZXIpO1xuICogYGBgXG4gKi9cbmNvbnN0IGNvbGxlY3RNZW1iZXJIb3N0cyA9IChcbiAgc291cmNlRmlsZTogdHMuU291cmNlRmlsZSxcbiAgY2hlY2tlcjogdHMuVHlwZUNoZWNrZXIsXG4pOiBNZW1iZXJIb3N0W10gPT4ge1xuICBjb25zdCBob3N0czogTWVtYmVySG9zdFtdID0gW107XG4gIGNvbnN0IHZpc2l0ID0gKG5vZGU6IHRzLk5vZGUpOiB2b2lkID0+IHtcbiAgICBpZiAodHMuaXNDbGFzc0RlY2xhcmF0aW9uKG5vZGUpKSB7XG4gICAgICBob3N0cy5wdXNoKHtcbiAgICAgICAgbWVtYmVyczogbm9kZS5tZW1iZXJzLFxuICAgICAgICBuYW1lOiBnZXRIb3N0TmFtZShub2RlKSxcbiAgICAgICAgbm9kZSxcbiAgICAgICAgc3ltYm9sOlxuICAgICAgICAgIG5vZGUubmFtZSA9PT0gdm9pZCAwXG4gICAgICAgICAgICA/IHZvaWQgMFxuICAgICAgICAgICAgOiBjaGVja2VyLmdldFN5bWJvbEF0TG9jYXRpb24obm9kZS5uYW1lKSxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAodHMuaXNJbnRlcmZhY2VEZWNsYXJhdGlvbihub2RlKSkge1xuICAgICAgaG9zdHMucHVzaCh7XG4gICAgICAgIG1lbWJlcnM6IG5vZGUubWVtYmVycyxcbiAgICAgICAgbmFtZTogZ2V0SG9zdE5hbWUobm9kZSksXG4gICAgICAgIG5vZGUsXG4gICAgICAgIHN5bWJvbDogY2hlY2tlci5nZXRTeW1ib2xBdExvY2F0aW9uKG5vZGUubmFtZSksXG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgdHMuaXNUeXBlQWxpYXNEZWNsYXJhdGlvbihub2RlKSAmJlxuICAgICAgdHMuaXNUeXBlTGl0ZXJhbE5vZGUobm9kZS50eXBlKVxuICAgICkge1xuICAgICAgaG9zdHMucHVzaCh7XG4gICAgICAgIG1lbWJlcnM6IG5vZGUudHlwZS5tZW1iZXJzLFxuICAgICAgICBuYW1lOiBnZXRIb3N0TmFtZShub2RlKSxcbiAgICAgICAgbm9kZSxcbiAgICAgICAgc3ltYm9sOiBjaGVja2VyLmdldFN5bWJvbEF0TG9jYXRpb24obm9kZS5uYW1lKSxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICB0cy5pc1ZhcmlhYmxlRGVjbGFyYXRpb24obm9kZSkgJiZcbiAgICAgIHRzLmlzSWRlbnRpZmllcihub2RlLm5hbWUpICYmXG4gICAgICB0cy5pc1ZhcmlhYmxlRGVjbGFyYXRpb25MaXN0KG5vZGUucGFyZW50KSAmJlxuICAgICAgKG5vZGUucGFyZW50LmZsYWdzICYgdHMuTm9kZUZsYWdzLkNvbnN0KSAhPT0gMFxuICAgICkge1xuICAgICAgY29uc3Qgb2JqZWN0TGl0ZXJhbCA9IGdldE9iamVjdExpdGVyYWwobm9kZS5pbml0aWFsaXplcik7XG5cbiAgICAgIGlmIChvYmplY3RMaXRlcmFsICE9PSB2b2lkIDApIHtcbiAgICAgICAgaG9zdHMucHVzaCh7XG4gICAgICAgICAgbWVtYmVyczogb2JqZWN0TGl0ZXJhbC5wcm9wZXJ0aWVzLFxuICAgICAgICAgIG5hbWU6IGdldEhvc3ROYW1lKG5vZGUpLFxuICAgICAgICAgIG5vZGUsXG4gICAgICAgICAgc3ltYm9sOiBjaGVja2VyLmdldFN5bWJvbEF0TG9jYXRpb24obm9kZS5uYW1lKSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdHMuZm9yRWFjaENoaWxkKG5vZGUsIHZpc2l0KTtcbiAgfTtcblxuICB2aXNpdChzb3VyY2VGaWxlKTtcblxuICByZXR1cm4gaG9zdHM7XG59O1xuXG5leHBvcnQge1xuICBjb2xsZWN0TWVtYmVySG9zdHMsXG4gIGdldE1lbWJlclN5bWJvbCxcbiAgZ2V0U3RhdGljTWVtYmVyTmFtZSxcbiAgaXNQdWJsaWNDbGFzc01lbWJlcixcbiAgaXNTdXBwb3J0ZWRNZW1iZXIsXG59O1xuIl19
@@ -0,0 +1,30 @@
1
+ import * as ts from "typescript";
2
+ import type { NoUnusedExportsState } from "../no-unused-exports/types.js";
3
+ /**
4
+ * Checks whether a member is reachable from a configured public API export.
5
+ * @param program TypeScript project program.
6
+ * @param state Normalized public API and test patterns.
7
+ * @param repoRoot Root directory used for glob matching.
8
+ * @param memberSymbol Member symbol being checked.
9
+ * @returns True when an API export exposes the member.
10
+ * @example
11
+ * ```typescript
12
+ * const exposed = isPublicApiMember(program, state, repoRoot, memberSymbol);
13
+ * ```
14
+ */
15
+ declare const isPublicApiMember: (program: ts.Program, state: NoUnusedExportsState, repoRoot: string, memberSymbol: ts.Symbol) => boolean;
16
+ /**
17
+ * Checks whether a host is exported from a configured public API file.
18
+ * @param program TypeScript project program.
19
+ * @param state Normalized public API and test patterns.
20
+ * @param repoRoot Root directory used for glob matching.
21
+ * @param hostSymbol Host declaration symbol.
22
+ * @returns True when the host is exposed by a non-test API file.
23
+ * @example
24
+ * ```typescript
25
+ * const isPublic = isPublicApiHost(program, state, repoRoot, hostSymbol);
26
+ * ```
27
+ */
28
+ declare const isPublicApiHost: (program: ts.Program, state: NoUnusedExportsState, repoRoot: string, hostSymbol: ts.Symbol | undefined) => boolean;
29
+ export { isPublicApiHost, isPublicApiMember };
30
+ //# sourceMappingURL=member-public-api-utilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"member-public-api-utilities.d.ts","sourceRoot":"","sources":["../../../../src/domain/architecture/no-unused-public-members/member-public-api-utilities.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AA2DvE;;;;;;;;;;;GAWG;AACH,QAAA,MAAM,iBAAiB,GACrB,SAAS,EAAE,CAAC,OAAO,EACnB,OAAO,oBAAoB,EAC3B,UAAU,MAAM,EAChB,cAAc,EAAE,CAAC,MAAM,KACtB,OA6CF,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,QAAA,MAAM,eAAe,GACnB,SAAS,EAAE,CAAC,OAAO,EACnB,OAAO,oBAAoB,EAC3B,UAAU,MAAM,EAChB,YAAY,EAAE,CAAC,MAAM,GAAG,SAAS,KAChC,OAsBF,CAAC;AAEF,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,CAAC"}
@@ -0,0 +1,101 @@
1
+ import path from "node:path";
2
+ import * as ts from "typescript";
3
+ import { isPublicApiFile, isTestFile, } from "../no-unused-exports/no-unused-exports-options.js";
4
+ import { isSameSymbol, resolveCanonicalSymbol, sourceFileExportsSymbol, } from "../no-unused-exports/no-unused-exports-symbol-utilities.js";
5
+ /**
6
+ * Checks whether a symbol is nested within an exported API type.
7
+ * @param type Type shape of an exported value or type.
8
+ * @param targetSymbol Symbol being searched for.
9
+ * @param checker TypeScript type checker.
10
+ * @param location Node used to resolve property types.
11
+ * @param visitedTypes Types already checked on this search path.
12
+ * @param depth Remaining nested property depth.
13
+ * @returns True when the target occurs in the exported type shape.
14
+ * @example
15
+ * ```typescript
16
+ * const exposed = typeContainsSymbol(type, member, checker, sourceFile, new Set(), 2);
17
+ * ```
18
+ */
19
+ const typeContainsSymbol = (type, targetSymbol, checker, location, visitedTypes, depth) => {
20
+ if (depth < 0 || visitedTypes.has(type)) {
21
+ return false;
22
+ }
23
+ visitedTypes.add(type);
24
+ for (const property of checker.getPropertiesOfType(type)) {
25
+ if (isSameSymbol(resolveCanonicalSymbol(property, checker), targetSymbol) ||
26
+ typeContainsSymbol(checker.getTypeOfSymbolAtLocation(property, location), targetSymbol, checker, location, visitedTypes, depth - 1)) {
27
+ return true;
28
+ }
29
+ }
30
+ return false;
31
+ };
32
+ /**
33
+ * Checks whether a member is reachable from a configured public API export.
34
+ * @param program TypeScript project program.
35
+ * @param state Normalized public API and test patterns.
36
+ * @param repoRoot Root directory used for glob matching.
37
+ * @param memberSymbol Member symbol being checked.
38
+ * @returns True when an API export exposes the member.
39
+ * @example
40
+ * ```typescript
41
+ * const exposed = isPublicApiMember(program, state, repoRoot, memberSymbol);
42
+ * ```
43
+ */
44
+ const isPublicApiMember = (program, state, repoRoot, memberSymbol) => {
45
+ const checker = program.getTypeChecker();
46
+ const targetSymbol = resolveCanonicalSymbol(memberSymbol, checker);
47
+ const normalizedRoot = path.resolve(repoRoot);
48
+ for (const sourceFile of program.getSourceFiles()) {
49
+ if (sourceFile.isDeclarationFile) {
50
+ continue;
51
+ }
52
+ const filename = path.resolve(sourceFile.fileName);
53
+ if (!isPublicApiFile(filename, state, normalizedRoot) ||
54
+ isTestFile(filename, state, normalizedRoot)) {
55
+ continue;
56
+ }
57
+ const moduleSymbol = checker.getSymbolAtLocation(sourceFile);
58
+ if (moduleSymbol === void 0) {
59
+ continue;
60
+ }
61
+ for (const exportedSymbol of checker.getExportsOfModule(moduleSymbol)) {
62
+ const canonicalExport = resolveCanonicalSymbol(exportedSymbol, checker);
63
+ if (isSameSymbol(canonicalExport, targetSymbol) ||
64
+ typeContainsSymbol(checker.getTypeOfSymbolAtLocation(canonicalExport, sourceFile), targetSymbol, checker, sourceFile, new Set(), 3)) {
65
+ return true;
66
+ }
67
+ }
68
+ }
69
+ return false;
70
+ };
71
+ /**
72
+ * Checks whether a host is exported from a configured public API file.
73
+ * @param program TypeScript project program.
74
+ * @param state Normalized public API and test patterns.
75
+ * @param repoRoot Root directory used for glob matching.
76
+ * @param hostSymbol Host declaration symbol.
77
+ * @returns True when the host is exposed by a non-test API file.
78
+ * @example
79
+ * ```typescript
80
+ * const isPublic = isPublicApiHost(program, state, repoRoot, hostSymbol);
81
+ * ```
82
+ */
83
+ const isPublicApiHost = (program, state, repoRoot, hostSymbol) => {
84
+ if (hostSymbol === void 0) {
85
+ return false;
86
+ }
87
+ const checker = program.getTypeChecker();
88
+ const normalizedRoot = path.resolve(repoRoot);
89
+ const canonicalHost = resolveCanonicalSymbol(hostSymbol, checker);
90
+ return program.getSourceFiles().some((sourceFile) => {
91
+ if (sourceFile.isDeclarationFile) {
92
+ return false;
93
+ }
94
+ const filename = path.resolve(sourceFile.fileName);
95
+ return (isPublicApiFile(filename, state, normalizedRoot) &&
96
+ !isTestFile(filename, state, normalizedRoot) &&
97
+ sourceFileExportsSymbol(sourceFile, checker, canonicalHost));
98
+ });
99
+ };
100
+ export { isPublicApiHost, isPublicApiMember };
101
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVtYmVyLXB1YmxpYy1hcGktdXRpbGl0aWVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2RvbWFpbi9hcmNoaXRlY3R1cmUvbm8tdW51c2VkLXB1YmxpYy1tZW1iZXJzL21lbWJlci1wdWJsaWMtYXBpLXV0aWxpdGllcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLElBQUksTUFBTSxXQUFXLENBQUM7QUFDN0IsT0FBTyxLQUFLLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFJakMsT0FBTyxFQUNMLGVBQWUsRUFDZixVQUFVLEdBQ1gsTUFBTSxnREFBZ0QsQ0FBQztBQUN4RCxPQUFPLEVBQ0wsWUFBWSxFQUNaLHNCQUFzQixFQUN0Qix1QkFBdUIsR0FDeEIsTUFBTSx5REFBeUQsQ0FBQztBQUVqRTs7Ozs7Ozs7Ozs7OztHQWFHO0FBQ0gsTUFBTSxrQkFBa0IsR0FBRyxDQUN6QixJQUFhLEVBQ2IsWUFBdUIsRUFDdkIsT0FBdUIsRUFDdkIsUUFBaUIsRUFDakIsWUFBMEIsRUFDMUIsS0FBYSxFQUNKLEVBQUU7SUFDWCxJQUFJLEtBQUssR0FBRyxDQUFDLElBQUksWUFBWSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQ3hDLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVELFlBQVksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7SUFFdkIsS0FBSyxNQUFNLFFBQVEsSUFBSSxPQUFPLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUN6RCxJQUNFLFlBQVksQ0FBQyxzQkFBc0IsQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLEVBQUUsWUFBWSxDQUFDO1lBQ3JFLGtCQUFrQixDQUNoQixPQUFPLENBQUMseUJBQXlCLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxFQUNyRCxZQUFZLEVBQ1osT0FBTyxFQUNQLFFBQVEsRUFDUixZQUFZLEVBQ1osS0FBSyxH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LEVBQUUsY0FBYyxDQUFDO1lBQzVDLHVCQUF1QixDQUFDLFVBQVUsRUFBRSxPQUFPLEVBQUUsYUFBYSxDQUFDLENBQzVELENBQUM7SUFDSixDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQztBQUVGLE9BQU8sRUFBRSxlQUFlLEVBQUUsaUJBQWlCLEVBQUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBwYXRoIGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCAqIGFzIHRzIGZyb20gXCJ0eXBlc2NyaXB0XCI7XG5cbmltcG9ydCB0eXBlIHsgTm9VbnVzZWRFeHBvcnRzU3RhdGUgfSBmcm9tIFwiLi4vbm8tdW51c2VkLWV4cG9ydHMvdHlwZXNcIjtcblxuaW1wb3J0IHtcbiAgaXNQdWJsaWNBcGlGaWxlLFxuICBpc1Rlc3RGaWxlLFxufSBmcm9tIFwiLi4vbm8tdW51c2VkLWV4cG9ydHMvbm8tdW51c2VkLWV4cG9ydHMtb3B0aW9uc1wiO1xuaW1wb3J0IHtcbiAgaXNTYW1lU3ltYm9sLFxuICByZXNvbHZlQ2Fub25pY2FsU3ltYm9sLFxuICBzb3VyY2VGaWxlRXhwb3J0c1N5bWJvbCxcbn0gZnJvbSBcIi4uL25vLXVudXNlZC1leHBvcnRzL25vLXVudXNlZC1leHBvcnRzLXN5bWJvbC11dGlsaXRpZXNcIjtcblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBhIHN5bWJvbCBpcyBuZXN0ZWQgd2l0aGluIGFuIGV4cG9ydGVkIEFQSSB0eXBlLlxuICogQHBhcmFtIHR5cGUgVHlwZSBzaGFwZSBvZiBhbiBleHBvcnRlZCB2YWx1ZSBvciB0eXBlLlxuICogQHBhcmFtIHRhcmdldFN5bWJvbCBTeW1ib2wgYmVpbmcgc2VhcmNoZWQgZm9yLlxuICogQHBhcmFtIGNoZWNrZXIgVHlwZVNjcmlwdCB0eXBlIGNoZWNrZXIuXG4gKiBAcGFyYW0gbG9jYXRpb24gTm9kZSB1c2VkIHRvIHJlc29sdmUgcHJvcGVydHkgdHlwZXMuXG4gKiBAcGFyYW0gdmlzaXRlZFR5cGVzIFR5cGVzIGFscmVhZHkgY2hlY2tlZCBvbiB0aGlzIHNlYXJjaCBwYXRoLlxuICogQHBhcmFtIGRlcHRoIFJlbWFpbmluZyBuZXN0ZWQgcHJvcGVydHkgZGVwdGguXG4gKiBAcmV0dXJucyBUcnVlIHdoZW4gdGhlIHRhcmdldCBvY2N1cnMgaW4gdGhlIGV4cG9ydGVkIHR5cGUgc2hhcGUuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgZXhwb3NlZCA9IHR5cGVDb250YWluc1N5bWJvbCh0eXBlLCBtZW1iZXIsIGNoZWNrZXIsIHNvdXJjZUZpbGUsIG5ldyBTZXQoKSwgMik7XG4gKiBgYGBcbiAqL1xuY29uc3QgdHlwZUNvbnRhaW5zU3ltYm9sID0gKFxuICB0eXBlOiB0cy5UeXBlLFxuICB0YXJnZXRTeW1ib2w6IHRzLlN5bWJvbCxcbiAgY2hlY2tlcjogdHMuVHlwZUNoZWNrZXIsXG4gIGxvY2F0aW9uOiB0cy5Ob2RlLFxuICB2aXNpdGVkVHlwZXM6IFNldDx0cy5UeXBlPixcbiAgZGVwdGg6IG51bWJlcixcbik6IGJvb2xlYW4gPT4ge1xuICBpZiAoZGVwdGggPCAwIHx8IHZpc2l0ZWRUeXBlcy5oYXModHlwZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB2aXNpdGVkVHlwZXMuYWRkKHR5cGUpO1xuXG4gIGZvciAoY29uc3QgcHJvcGVydHkgb2YgY2hlY2tlci5nZXRQcm9wZXJ0aWVzT2ZUeXBlKHR5cGUpKSB7XG4gICAgaWYgKFxuICAgICAgaXNTYW1lU3ltYm9sKHJlc29sdmVDYW5vbmljYWxTeW1ib2wocHJvcGVydHksIGNoZWNrZXIpLCB0YXJnZXRTeW1ib2wpIHx8XG4gICAgICB0eXBlQ29udGFpbnNTeW1ib2woXG4gICAgICAgIGNoZWNrZXIuZ2V0VHlwZU9mU3ltYm9sQXRMb2NhdGlvbihwcm9wZXJ0eSwgbG9jYXRpb24pLFxuICAgICAgICB0YXJnZXRTeW1ib2wsXG4gICAgICAgIGNoZWNrZXIsXG4gICAgICAgIGxvY2F0aW9uLFxuICAgICAgICB2aXNpdGVkVHlwZXMsXG4gICAgICAgIGRlcHRoIC0gMSxcbiAgICAgIClcbiAgICApIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn07XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgYSBtZW1iZXIgaXMgcmVhY2hhYmxlIGZyb20gYSBjb25maWd1cmVkIHB1YmxpYyBBUEkgZXhwb3J0LlxuICogQHBhcmFtIHByb2dyYW0gVHlwZVNjcmlwdCBwcm9qZWN0IHByb2dyYW0uXG4gKiBAcGFyYW0gc3RhdGUgTm9ybWFsaXplZCBwdWJsaWMgQVBJIGFuZCB0ZXN0IHBhdHRlcm5zLlxuICogQHBhcmFtIHJlcG9Sb290IFJvb3QgZGlyZWN0b3J5IHVzZWQgZm9yIGdsb2IgbWF0Y2hpbmcuXG4gKiBAcGFyYW0gbWVtYmVyU3ltYm9sIE1lbWJlciBzeW1ib2wgYmVpbmcgY2hlY2tlZC5cbiAqIEByZXR1cm5zIFRydWUgd2hlbiBhbiBBUEkgZXhwb3J0IGV4cG9zZXMgdGhlIG1lbWJlci5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBleHBvc2VkID0gaXNQdWJsaWNBcGlNZW1iZXIocHJvZ3JhbSwgc3RhdGUsIHJlcG9Sb290LCBtZW1iZXJTeW1ib2wpO1xuICogYGBgXG4gKi9cbmNvbnN0IGlzUHVibGljQXBpTWVtYmVyID0gKFxuICBwcm9ncmFtOiB0cy5Qcm9ncmFtLFxuICBzdGF0ZTogTm9VbnVzZWRFeHBvcnRzU3RhdGUsXG4gIHJlcG9Sb290OiBzdHJpbmcsXG4gIG1lbWJlclN5bWJvbDogdHMuU3ltYm9sLFxuKTogYm9vbGVhbiA9PiB7XG4gIGNvbnN0IGNoZWNrZXIgPSBwcm9ncmFtLmdldFR5cGVDaGVja2VyKCk7XG4gIGNvbnN0IHRhcmdldFN5bWJvbCA9IHJlc29sdmVDYW5vbmljYWxTeW1ib2wobWVtYmVyU3ltYm9sLCBjaGVja2VyKTtcbiAgY29uc3Qgbm9ybWFsaXplZFJvb3QgPSBwYXRoLnJlc29sdmUocmVwb1Jvb3QpO1xuXG4gIGZvciAoY29uc3Qgc291cmNlRmlsZSBvZiBwcm9ncmFtLmdldFNvdXJjZUZpbGVzKCkpIHtcbiAgICBpZiAoc291cmNlRmlsZS5pc0RlY2xhcmF0aW9uRmlsZSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgY29uc3QgZmlsZW5hbWUgPSBwYXRoLnJlc29sdmUoc291cmNlRmlsZS5maWxlTmFtZSk7XG5cbiAgICBpZiAoXG4gICAgICAhaXNQdWJsaWNBcGlGaWxlKGZpbGVuYW1lLCBzdGF0ZSwgbm9ybWFsaXplZFJvb3QpIHx8XG4gICAgICBpc1Rlc3RGaWxlKGZpbGVuYW1lLCBzdGF0ZSwgbm9ybWFsaXplZFJvb3QpXG4gICAgKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBtb2R1bGVTeW1ib2wgPSBjaGVja2VyLmdldFN5bWJvbEF0TG9jYXRpb24oc291cmNlRmlsZSk7XG5cbiAgICBpZiAobW9kdWxlU3ltYm9sID09PSB2b2lkIDApIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZXhwb3J0ZWRTeW1ib2wgb2YgY2hlY2tlci5nZXRFeHBvcnRzT2ZNb2R1bGUobW9kdWxlU3ltYm9sKSkge1xuICAgICAgY29uc3QgY2Fub25pY2FsRXhwb3J0ID0gcmVzb2x2ZUNhbm9uaWNhbFN5bWJvbChleHBvcnRlZFN5bWJvbCwgY2hlY2tlcik7XG5cbiAgICAgIGlmIChcbiAgICAgICAgaXNTYW1lU3ltYm9sKGNhbm9uaWNhbEV4cG9ydCwgdGFyZ2V0U3ltYm9sKSB8fFxuICAgICAgICB0eXBlQ29udGFpbnNTeW1ib2woXG4gICAgICAgICAgY2hlY2tlci5nZXRUeXBlT2ZTeW1ib2xBdExvY2F0aW9uKGNhbm9uaWNhbEV4cG9ydCwgc291cmNlRmlsZSksXG4gICAgICAgICAgdGFyZ2V0U3ltYm9sLFxuICAgICAgICAgIGNoZWNrZXIsXG4gICAgICAgICAgc291cmNlRmlsZSxcbiAgICAgICAgICBuZXcgU2V0KCksXG4gICAgICAgICAgMyxcbiAgICAgICAgKVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn07XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgYSBob3N0IGlzIGV4cG9ydGVkIGZyb20gYSBjb25maWd1cmVkIHB1YmxpYyBBUEkgZmlsZS5cbiAqIEBwYXJhbSBwcm9ncmFtIFR5cGVTY3JpcHQgcHJvamVjdCBwcm9ncmFtLlxuICogQHBhcmFtIHN0YXRlIE5vcm1hbGl6ZWQgcHVibGljIEFQSSBhbmQgdGVzdCBwYXR0ZXJucy5cbiAqIEBwYXJhbSByZXBvUm9vdCBSb290IGRpcmVjdG9yeSB1c2VkIGZvciBnbG9iIG1hdGNoaW5nLlxuICogQHBhcmFtIGhvc3RTeW1ib2wgSG9zdCBkZWNsYXJhdGlvbiBzeW1ib2wuXG4gKiBAcmV0dXJucyBUcnVlIHdoZW4gdGhlIGhvc3QgaXMgZXhwb3NlZCBieSBhIG5vbi10ZXN0IEFQSSBmaWxlLlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IGlzUHVibGljID0gaXNQdWJsaWNBcGlIb3N0KHByb2dyYW0sIHN0YXRlLCByZXBvUm9vdCwgaG9zdFN5bWJvbCk7XG4gKiBgYGBcbiAqL1xuY29uc3QgaXNQdWJsaWNBcGlIb3N0ID0gKFxuICBwcm9ncmFtOiB0cy5Qcm9ncmFtLFxuICBzdGF0ZTogTm9VbnVzZWRFeHBvcnRzU3RhdGUsXG4gIHJlcG9Sb290OiBzdHJpbmcsXG4gIGhvc3RTeW1ib2w6IHRzLlN5bWJvbCB8IHVuZGVmaW5lZCxcbik6IGJvb2xlYW4gPT4ge1xuICBpZiAoaG9zdFN5bWJvbCA9PT0gdm9pZCAwKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgY29uc3QgY2hlY2tlciA9IHByb2dyYW0uZ2V0VHlwZUNoZWNrZXIoKTtcbiAgY29uc3Qgbm9ybWFsaXplZFJvb3QgPSBwYXRoLnJlc29sdmUocmVwb1Jvb3QpO1xuICBjb25zdCBjYW5vbmljYWxIb3N0ID0gcmVzb2x2ZUNhbm9uaWNhbFN5bWJvbChob3N0U3ltYm9sLCBjaGVja2VyKTtcblxuICByZXR1cm4gcHJvZ3JhbS5nZXRTb3VyY2VGaWxlcygpLnNvbWUoKHNvdXJjZUZpbGUpID0+IHtcbiAgICBpZiAoc291cmNlRmlsZS5pc0RlY2xhcmF0aW9uRmlsZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IGZpbGVuYW1lID0gcGF0aC5yZXNvbHZlKHNvdXJjZUZpbGUuZmlsZU5hbWUpO1xuXG4gICAgcmV0dXJuIChcbiAgICAgIGlzUHVibGljQXBpRmlsZShmaWxlbmFtZSwgc3RhdGUsIG5vcm1hbGl6ZWRSb290KSAmJlxuICAgICAgIWlzVGVzdEZpbGUoZmlsZW5hbWUsIHN0YXRlLCBub3JtYWxpemVkUm9vdCkgJiZcbiAgICAgIHNvdXJjZUZpbGVFeHBvcnRzU3ltYm9sKHNvdXJjZUZpbGUsIGNoZWNrZXIsIGNhbm9uaWNhbEhvc3QpXG4gICAgKTtcbiAgfSk7XG59O1xuXG5leHBvcnQgeyBpc1B1YmxpY0FwaUhvc3QsIGlzUHVibGljQXBpTWVtYmVyIH07XG4iXX0=
@@ -0,0 +1,28 @@
1
+ import * as ts from "typescript";
2
+ import type { PublicMember } from "./member-declaration-utilities.js";
3
+ /**
4
+ * Checks whether an object property is supplied to a typed call boundary.
5
+ * @param node Candidate property assignment.
6
+ * @param checker TypeScript type checker.
7
+ * @param member Member whose usage is being checked.
8
+ * @returns True when an external call contract accepts the member shape.
9
+ * @example
10
+ * ```typescript
11
+ * const used = isCallArgumentMember(node, checker, member);
12
+ * ```
13
+ */
14
+ declare const isCallArgumentMember: (node: ts.Node, checker: ts.TypeChecker, member: PublicMember) => boolean;
15
+ /**
16
+ * Checks whether a property value is forwarded into an external object contract.
17
+ * @param node Candidate outer object property.
18
+ * @param checker TypeScript type checker.
19
+ * @param member Member whose host value is being forwarded.
20
+ * @returns True when the receiving property accepts the host shape.
21
+ * @example
22
+ * ```typescript
23
+ * const used = isObjectContractHandoff(node, checker, member);
24
+ * ```
25
+ */
26
+ declare const isObjectContractHandoff: (node: ts.Node, checker: ts.TypeChecker, member: PublicMember) => boolean;
27
+ export { isCallArgumentMember, isObjectContractHandoff };
28
+ //# sourceMappingURL=member-usage-handoff-utilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"member-usage-handoff-utilities.d.ts","sourceRoot":"","sources":["../../../../src/domain/architecture/no-unused-public-members/member-usage-handoff-utilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AA0FnE;;;;;;;;;;GAUG;AACH,QAAA,MAAM,oBAAoB,GACxB,MAAM,EAAE,CAAC,IAAI,EACb,SAAS,EAAE,CAAC,WAAW,EACvB,QAAQ,YAAY,KACnB,OA8BF,CAAC;AAEF;;;;;;;;;;GAUG;AACH,QAAA,MAAM,uBAAuB,GAC3B,MAAM,EAAE,CAAC,IAAI,EACb,SAAS,EAAE,CAAC,WAAW,EACvB,QAAQ,YAAY,KACnB,OAkDF,CAAC;AAEF,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,CAAC"}
@@ -0,0 +1,125 @@
1
+ import * as ts from "typescript";
2
+ import { getContextualPropertyType, isMemberHandoff, } from "./member-usage-type-utilities.js";
3
+ /**
4
+ * Finds a call argument's resolved parameter type.
5
+ * @param call Call expression containing the argument.
6
+ * @param argument Argument expression to inspect.
7
+ * @param checker TypeScript type checker.
8
+ * @returns Parameter type when TypeScript resolves the call.
9
+ * @example
10
+ * ```typescript
11
+ * const parameterType = getCallArgumentType(call, argument, checker);
12
+ * ```
13
+ */
14
+ const getCallArgumentType = (call, argument, checker) => {
15
+ const contextualType = checker.getContextualType(argument);
16
+ if (contextualType !== void 0) {
17
+ return contextualType;
18
+ }
19
+ const argumentIndex = call.arguments.indexOf(argument);
20
+ const signature = checker.getResolvedSignature(call);
21
+ const parameter = signature === void 0 ? void 0 : signature.parameters[argumentIndex];
22
+ return parameter === void 0
23
+ ? void 0
24
+ : checker.getTypeOfSymbolAtLocation(parameter, call);
25
+ };
26
+ /**
27
+ * Checks whether a contextual property comes from an external declaration.
28
+ * @param objectType Contextual type of the containing object literal.
29
+ * @param propertyName Property name in the object literal.
30
+ * @param checker TypeScript type checker.
31
+ * @returns True when the contract is declared outside the project source.
32
+ * @example
33
+ * ```typescript
34
+ * const external = isExternalPropertyContract(objectType, "docs", checker);
35
+ * ```
36
+ */
37
+ const isExternalPropertyContract = (objectType, propertyName, checker) => {
38
+ const property = objectType === void 0
39
+ ? void 0
40
+ : checker.getPropertyOfType(objectType, propertyName);
41
+ return (property?.declarations?.some((declaration) => declaration.getSourceFile().isDeclarationFile) ?? false);
42
+ };
43
+ /**
44
+ * Checks whether a call resolves to a declaration with a local implementation.
45
+ * @param call Call expression to inspect.
46
+ * @param checker TypeScript type checker.
47
+ * @returns True when the resolved declaration has a body.
48
+ * @example
49
+ * ```typescript
50
+ * const implemented = hasCallImplementation(call, checker);
51
+ * ```
52
+ */
53
+ const hasCallImplementation = (call, checker) => {
54
+ const declaration = checker.getResolvedSignature(call)?.getDeclaration();
55
+ return (declaration !== void 0 &&
56
+ "body" in declaration &&
57
+ declaration.body !== void 0);
58
+ };
59
+ /**
60
+ * Checks whether an object property is supplied to a typed call boundary.
61
+ * @param node Candidate property assignment.
62
+ * @param checker TypeScript type checker.
63
+ * @param member Member whose usage is being checked.
64
+ * @returns True when an external call contract accepts the member shape.
65
+ * @example
66
+ * ```typescript
67
+ * const used = isCallArgumentMember(node, checker, member);
68
+ * ```
69
+ */
70
+ const isCallArgumentMember = (node, checker, member) => {
71
+ if (!ts.isPropertyAssignment(node) ||
72
+ (!ts.isIdentifier(node.name) && !ts.isStringLiteralLike(node.name)) ||
73
+ !ts.isObjectLiteralExpression(node.parent)) {
74
+ return false;
75
+ }
76
+ const call = node.parent.parent;
77
+ if (!ts.isCallExpression(call) ||
78
+ hasCallImplementation(call, checker) ||
79
+ !call.arguments.some((argument) => argument === node.parent)) {
80
+ return false;
81
+ }
82
+ const targetType = getCallArgumentType(call, node.parent, checker);
83
+ return (node.name.text === member.memberName &&
84
+ isMemberHandoff(checker.getTypeAtLocation(node.parent), targetType, member, checker));
85
+ };
86
+ /**
87
+ * Checks whether a property value is forwarded into an external object contract.
88
+ * @param node Candidate outer object property.
89
+ * @param checker TypeScript type checker.
90
+ * @param member Member whose host value is being forwarded.
91
+ * @returns True when the receiving property accepts the host shape.
92
+ * @example
93
+ * ```typescript
94
+ * const used = isObjectContractHandoff(node, checker, member);
95
+ * ```
96
+ */
97
+ const isObjectContractHandoff = (node, checker, member) => {
98
+ if (ts.isPropertyAssignment(node) &&
99
+ ts.isObjectLiteralExpression(node.parent)) {
100
+ const name = node.name;
101
+ if (!ts.isIdentifier(name) && !ts.isStringLiteralLike(name)) {
102
+ return false;
103
+ }
104
+ const objectType = checker.getContextualType(node.parent);
105
+ if (!isExternalPropertyContract(objectType, name.text, checker)) {
106
+ return false;
107
+ }
108
+ const sourceType = checker.getTypeAtLocation(node.initializer);
109
+ const targetType = getContextualPropertyType(objectType, name.text, node, checker);
110
+ return isMemberHandoff(sourceType, targetType, member, checker);
111
+ }
112
+ if (ts.isShorthandPropertyAssignment(node) &&
113
+ ts.isObjectLiteralExpression(node.parent)) {
114
+ const objectType = checker.getContextualType(node.parent);
115
+ if (!isExternalPropertyContract(objectType, node.name.text, checker)) {
116
+ return false;
117
+ }
118
+ const sourceType = checker.getTypeAtLocation(node.name);
119
+ const targetType = getContextualPropertyType(objectType, node.name.text, node, checker);
120
+ return isMemberHandoff(sourceType, targetType, member, checker);
121
+ }
122
+ return false;
123
+ };
124
+ export { isCallArgumentMember, isObjectContractHandoff };
125
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVtYmVyLXVzYWdlLWhhbmRvZmYtdXRpbGl0aWVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2RvbWFpbi9hcmNoaXRlY3R1cmUvbm8tdW51c2VkLXB1YmxpYy1tZW1iZXJzL21lbWJlci11c2FnZS1oYW5kb2ZmLXV0aWxpdGllcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxNQUFNLFlBQVksQ0FBQztBQUlqQyxPQUFPLEVBQ0wseUJBQXlCLEVBQ3pCLGVBQWUsR0FDaEIsTUFBTSwrQkFBK0IsQ0FBQztBQUV2Qzs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBTSxtQkFBbUIsR0FBRyxDQUMxQixJQUF1QixFQUN2QixRQUF1QixFQUN2QixPQUF1QixFQUNGLEVBQUU7SUFDdkIsTUFBTSxjQUFjLEdBQUcsT0FBTyxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBRTNELElBQUksY0FBYyxLQUFLLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDOUIsT0FBTyxjQUFjLENBQUM7SUFDeEIsQ0FBQztJQUVELE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3ZELE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNyRCxNQUFNLFNBQVMsR0FDYixTQUFTLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBRXRFLE9BQU8sU0FBUyxLQUFLLEtBQUssQ0FBQztRQUN6QixDQUFDLENBQUMsS0FBSyxDQUFDO1FBQ1IsQ0FBQyxDQUFDLE9BQU8sQ0FBQyx5QkFBeUIsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDekQsQ0FBQyxDQUFDO0FBRUY7Ozs7Ozs7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QUVGLE9BQU8sZUFBZSxDQUFDLFVBQVUsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ2xFLENBQUM7SUFFRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUMsQ0FBQztBQUVGLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSx1QkFBdUIsRUFBRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgdHMgZnJvbSBcInR5cGVzY3JpcHRcIjtcblxuaW1wb3J0IHR5cGUgeyBQdWJsaWNNZW1iZXIgfSBmcm9tIFwiLi9tZW1iZXItZGVjbGFyYXRpb24tdXRpbGl0aWVzXCI7XG5cbmltcG9ydCB7XG4gIGdldENvbnRleHR1YWxQcm9wZXJ0eVR5cGUsXG4gIGlzTWVtYmVySGFuZG9mZixcbn0gZnJvbSBcIi4vbWVtYmVyLXVzYWdlLXR5cGUtdXRpbGl0aWVzXCI7XG5cbi8qKlxuICogRmluZHMgYSBjYWxsIGFyZ3VtZW50J3MgcmVzb2x2ZWQgcGFyYW1ldGVyIHR5cGUuXG4gKiBAcGFyYW0gY2FsbCBDYWxsIGV4cHJlc3Npb24gY29udGFpbmluZyB0aGUgYXJndW1lbnQuXG4gKiBAcGFyYW0gYXJndW1lbnQgQXJndW1lbnQgZXhwcmVzc2lvbiB0byBpbnNwZWN0LlxuICogQHBhcmFtIGNoZWNrZXIgVHlwZVNjcmlwdCB0eXBlIGNoZWNrZXIuXG4gKiBAcmV0dXJucyBQYXJhbWV0ZXIgdHlwZSB3aGVuIFR5cGVTY3JpcHQgcmVzb2x2ZXMgdGhlIGNhbGwuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgcGFyYW1ldGVyVHlwZSA9IGdldENhbGxBcmd1bWVudFR5cGUoY2FsbCwgYXJndW1lbnQsIGNoZWNrZXIpO1xuICogYGBgXG4gKi9cbmNvbnN0IGdldENhbGxBcmd1bWVudFR5cGUgPSAoXG4gIGNhbGw6IHRzLkNhbGxFeHByZXNzaW9uLFxuICBhcmd1bWVudDogdHMuRXhwcmVzc2lvbixcbiAgY2hlY2tlcjogdHMuVHlwZUNoZWNrZXIsXG4pOiB0cy5UeXBlIHwgdW5kZWZpbmVkID0+IHtcbiAgY29uc3QgY29udGV4dHVhbFR5cGUgPSBjaGVja2VyLmdldENvbnRleHR1YWxUeXBlKGFyZ3VtZW50KTtcblxuICBpZiAoY29udGV4dHVhbFR5cGUgIT09IHZvaWQgMCkge1xuICAgIHJldHVybiBjb250ZXh0dWFsVHlwZTtcbiAgfVxuXG4gIGNvbnN0IGFyZ3VtZW50SW5kZXggPSBjYWxsLmFyZ3VtZW50cy5pbmRleE9mKGFyZ3VtZW50KTtcbiAgY29uc3Qgc2lnbmF0dXJlID0gY2hlY2tlci5nZXRSZXNvbHZlZFNpZ25hdHVyZShjYWxsKTtcbiAgY29uc3QgcGFyYW1ldGVyID1cbiAgICBzaWduYXR1cmUgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHNpZ25hdHVyZS5wYXJhbWV0ZXJzW2FyZ3VtZW50SW5kZXhdO1xuXG4gIHJldHVybiBwYXJhbWV0ZXIgPT09IHZvaWQgMFxuICAgID8gdm9pZCAwXG4gICAgOiBjaGVja2VyLmdldFR5cGVPZlN5bWJvbEF0TG9jYXRpb24ocGFyYW1ldGVyLCBjYWxsKTtcbn07XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgYSBjb250ZXh0dWFsIHByb3BlcnR5IGNvbWVzIGZyb20gYW4gZXh0ZXJuYWwgZGVjbGFyYXRpb24uXG4gKiBAcGFyYW0gb2JqZWN0VHlwZSBDb250ZXh0dWFsIHR5cGUgb2YgdGhlIGNvbnRhaW5pbmcgb2JqZWN0IGxpdGVyYWwuXG4gKiBAcGFyYW0gcHJvcGVydHlOYW1lIFByb3BlcnR5IG5hbWUgaW4gdGhlIG9iamVjdCBsaXRlcmFsLlxuICogQHBhcmFtIGNoZWNrZXIgVHlwZVNjcmlwdCB0eXBlIGNoZWNrZXIuXG4gKiBAcmV0dXJucyBUcnVlIHdoZW4gdGhlIGNvbnRyYWN0IGlzIGRlY2xhcmVkIG91dHNpZGUgdGhlIHByb2plY3Qgc291cmNlLlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IGV4dGVybmFsID0gaXNFeHRlcm5hbFByb3BlcnR5Q29udHJhY3Qob2JqZWN0VHlwZSwgXCJkb2NzXCIsIGNoZWNrZXIpO1xuICogYGBgXG4gKi9cbmNvbnN0IGlzRXh0ZXJuYWxQcm9wZXJ0eUNvbnRyYWN0ID0gKFxuICBvYmplY3RUeXBlOiB0cy5UeXBlIHwgdW5kZWZpbmVkLFxuICBwcm9wZXJ0eU5hbWU6IHN0cmluZyxcbiAgY2hlY2tlcjogdHMuVHlwZUNoZWNrZXIsXG4pOiBib29sZWFuID0+IHtcbiAgY29uc3QgcHJvcGVydHkgPVxuICAgIG9iamVjdFR5cGUgPT09IHZvaWQgMFxuICAgICAgPyB2b2lkIDBcbiAgICAgIDogY2hlY2tlci5nZXRQcm9wZXJ0eU9mVHlwZShvYmplY3RUeXBlLCBwcm9wZXJ0eU5hbWUpO1xuXG4gIHJldHVybiAoXG4gICAgcHJvcGVydHk/LmRlY2xhcmF0aW9ucz8uc29tZShcbiAgICAgIChkZWNsYXJhdGlvbikgPT4gZGVjbGFyYXRpb24uZ2V0U291cmNlRmlsZSgpLmlzRGVjbGFyYXRpb25GaWxlLFxuICAgICkgPz8gZmFsc2VcbiAgKTtcbn07XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgYSBjYWxsIHJlc29sdmVzIHRvIGEgZGVjbGFyYXRpb24gd2l0aCBhIGxvY2FsIGltcGxlbWVudGF0aW9uLlxuICogQHBhcmFtIGNhbGwgQ2FsbCBleHByZXNzaW9uIHRvIGluc3BlY3QuXG4gKiBAcGFyYW0gY2hlY2tlciBUeXBlU2NyaXB0IHR5cGUgY2hlY2tlci5cbiAqIEByZXR1cm5zIFRydWUgd2hlbiB0aGUgcmVzb2x2ZWQgZGVjbGFyYXRpb24gaGFzIGEgYm9keS5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBpbXBsZW1lbnRlZCA9IGhhc0NhbGxJbXBsZW1lbnRhdGlvbihjYWxsLCBjaGVja2VyKTtcbiAqIGBgYFxuICovXG5jb25zdCBoYXNDYWxsSW1wbGVtZW50YXRpb24gPSAoXG4gIGNhbGw6IHRzLkNhbGxFeHByZXNzaW9uLFxuICBjaGVja2VyOiB0cy5UeXBlQ2hlY2tlcixcbik6IGJvb2xlYW4gPT4ge1xuICBjb25zdCBkZWNsYXJhdGlvbiA9IGNoZWNrZXIuZ2V0UmVzb2x2ZWRTaWduYXR1cmUoY2FsbCk/LmdldERlY2xhcmF0aW9uKCk7XG5cbiAgcmV0dXJuIChcbiAgICBkZWNsYXJhdGlvbiAhPT0gdm9pZCAwICYmXG4gICAgXCJib2R5XCIgaW4gZGVjbGFyYXRpb24gJiZcbiAgICBkZWNsYXJhdGlvbi5ib2R5ICE9PSB2b2lkIDBcbiAgKTtcbn07XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgYW4gb2JqZWN0IHByb3BlcnR5IGlzIHN1cHBsaWVkIHRvIGEgdHlwZWQgY2FsbCBib3VuZGFyeS5cbiAqIEBwYXJhbSBub2RlIENhbmRpZGF0ZSBwcm9wZXJ0eSBhc3NpZ25tZW50LlxuICogQHBhcmFtIGNoZWNrZXIgVHlwZVNjcmlwdCB0eXBlIGNoZWNrZXIuXG4gKiBAcGFyYW0gbWVtYmVyIE1lbWJlciB3aG9zZSB1c2FnZSBpcyBiZWluZyBjaGVja2VkLlxuICogQHJldHVybnMgVHJ1ZSB3aGVuIGFuIGV4dGVybmFsIGNhbGwgY29udHJhY3QgYWNjZXB0cyB0aGUgbWVtYmVyIHNoYXBlLlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHVzZWQgPSBpc0NhbGxBcmd1bWVudE1lbWJlcihub2RlLCBjaGVja2VyLCBtZW1iZXIpO1xuICogYGBgXG4gKi9cbmNvbnN0IGlzQ2FsbEFyZ3VtZW50TWVtYmVyID0gKFxuICBub2RlOiB0cy5Ob2RlLFxuICBjaGVja2VyOiB0cy5UeXBlQ2hlY2tlcixcbiAgbWVtYmVyOiBQdWJsaWNNZW1iZXIsXG4pOiBib29sZWFuID0+IHtcbiAgaWYgKFxuICAgICF0cy5pc1Byb3BlcnR5QXNzaWdubWVudChub2RlKSB8fFxuICAgICghdHMuaXNJZGVudGlmaWVyKG5vZGUubmFtZSkgJiYgIXRzLmlzU3RyaW5nTGl0ZXJhbExpa2Uobm9kZS5uYW1lKSkgfHxcbiAgICAhdHMuaXNPYmplY3RMaXRlcmFsRXhwcmVzc2lvbihub2RlLnBhcmVudClcbiAgKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgY29uc3QgY2FsbCA9IG5vZGUucGFyZW50LnBhcmVudDtcblxuICBpZiAoXG4gICAgIXRzLmlzQ2FsbEV4cHJlc3Npb24oY2FsbCkgfHxcbiAgICBoYXNDYWxsSW1wbGVtZW50YXRpb24oY2FsbCwgY2hlY2tlcikgfHxcbiAgICAhY2FsbC5hcmd1bWVudHMuc29tZSgoYXJndW1lbnQpID0+IGFyZ3VtZW50ID09PSBub2RlLnBhcmVudClcbiAgKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgY29uc3QgdGFyZ2V0VHlwZSA9IGdldENhbGxBcmd1bWVudFR5cGUoY2FsbCwgbm9kZS5wYXJlbnQsIGNoZWNrZXIpO1xuXG4gIHJldHVybiAoXG4gICAgbm9kZS5uYW1lLnRleHQgPT09IG1lbWJlci5tZW1iZXJOYW1lICYmXG4gICAgaXNNZW1iZXJIYW5kb2ZmKFxuICAgICAgY2hlY2tlci5nZXRUeXBlQXRMb2NhdGlvbihub2RlLnBhcmVudCksXG4gICAgICB0YXJnZXRUeXBlLFxuICAgICAgbWVtYmVyLFxuICAgICAgY2hlY2tlcixcbiAgICApXG4gICk7XG59O1xuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIGEgcHJvcGVydHkgdmFsdWUgaXMgZm9yd2FyZGVkIGludG8gYW4gZXh0ZXJuYWwgb2JqZWN0IGNvbnRyYWN0LlxuICogQHBhcmFtIG5vZGUgQ2FuZGlkYXRlIG91dGVyIG9iamVjdCBwcm9wZXJ0eS5cbiAqIEBwYXJhbSBjaGVja2VyIFR5cGVTY3JpcHQgdHlwZSBjaGVja2VyLlxuICogQHBhcmFtIG1lbWJlciBNZW1iZXIgd2hvc2UgaG9zdCB2YWx1ZSBpcyBiZWluZyBmb3J3YXJkZWQuXG4gKiBAcmV0dXJucyBUcnVlIHdoZW4gdGhlIHJlY2VpdmluZyBwcm9wZXJ0eSBhY2NlcHRzIHRoZSBob3N0IHNoYXBlLlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHVzZWQgPSBpc09iamVjdENvbnRyYWN0SGFuZG9mZihub2RlLCBjaGVja2VyLCBtZW1iZXIpO1xuICogYGBgXG4gKi9cbmNvbnN0IGlzT2JqZWN0Q29udHJhY3RIYW5kb2ZmID0gKFxuICBub2RlOiB0cy5Ob2RlLFxuICBjaGVja2VyOiB0cy5UeXBlQ2hlY2tlcixcbiAgbWVtYmVyOiBQdWJsaWNNZW1iZXIsXG4pOiBib29sZWFuID0+IHtcbiAgaWYgKFxuICAgIHRzLmlzUHJvcGVydHlBc3NpZ25tZW50KG5vZGUpICYmXG4gICAgdHMuaXNPYmplY3RMaXRlcmFsRXhwcmVzc2lvbihub2RlLnBhcmVudClcbiAgKSB7XG4gICAgY29uc3QgbmFtZSA9IG5vZGUubmFtZTtcblxuICAgIGlmICghdHMuaXNJZGVudGlmaWVyKG5hbWUpICYmICF0cy5pc1N0cmluZ0xpdGVyYWxMaWtlKG5hbWUpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgY29uc3Qgb2JqZWN0VHlwZSA9IGNoZWNrZXIuZ2V0Q29udGV4dHVhbFR5cGUobm9kZS5wYXJlbnQpO1xuXG4gICAgaWYgKCFpc0V4dGVybmFsUHJvcGVydHlDb250cmFjdChvYmplY3RUeXBlLCBuYW1lLnRleHQsIGNoZWNrZXIpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgY29uc3Qgc291cmNlVHlwZSA9IGNoZWNrZXIuZ2V0VHlwZUF0TG9jYXRpb24obm9kZS5pbml0aWFsaXplcik7XG4gICAgY29uc3QgdGFyZ2V0VHlwZSA9IGdldENvbnRleHR1YWxQcm9wZXJ0eVR5cGUoXG4gICAgICBvYmplY3RUeXBlLFxuICAgICAgbmFtZS50ZXh0LFxuICAgICAgbm9kZSxcbiAgICAgIGNoZWNrZXIsXG4gICAgKTtcblxuICAgIHJldHVybiBpc01lbWJlckhhbmRvZmYoc291cmNlVHlwZSwgdGFyZ2V0VHlwZSwgbWVtYmVyLCBjaGVja2VyKTtcbiAgfVxuXG4gIGlmIChcbiAgICB0cy5pc1Nob3J0aGFuZFByb3BlcnR5QXNzaWdubWVudChub2RlKSAmJlxuICAgIHRzLmlzT2JqZWN0TGl0ZXJhbEV4cHJlc3Npb24obm9kZS5wYXJlbnQpXG4gICkge1xuICAgIGNvbnN0IG9iamVjdFR5cGUgPSBjaGVja2VyLmdldENvbnRleHR1YWxUeXBlKG5vZGUucGFyZW50KTtcblxuICAgIGlmICghaXNFeHRlcm5hbFByb3BlcnR5Q29udHJhY3Qob2JqZWN0VHlwZSwgbm9kZS5uYW1lLnRleHQsIGNoZWNrZXIpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgY29uc3Qgc291cmNlVHlwZSA9IGNoZWNrZXIuZ2V0VHlwZUF0TG9jYXRpb24obm9kZS5uYW1lKTtcbiAgICBjb25zdCB0YXJnZXRUeXBlID0gZ2V0Q29udGV4dHVhbFByb3BlcnR5VHlwZShcbiAgICAgIG9iamVjdFR5cGUsXG4gICAgICBub2RlLm5hbWUudGV4dCxcbiAgICAgIG5vZGUsXG4gICAgICBjaGVja2VyLFxuICAgICk7XG5cbiAgICByZXR1cm4gaXNNZW1iZXJIYW5kb2ZmKHNvdXJjZVR5cGUsIHRhcmdldFR5cGUsIG1lbWJlciwgY2hlY2tlcik7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59O1xuXG5leHBvcnQgeyBpc0NhbGxBcmd1bWVudE1lbWJlciwgaXNPYmplY3RDb250cmFjdEhhbmRvZmYgfTtcbiJdfQ==
@@ -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;AA8DnE;;;;;;;;;;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,OAqBF,CAAC;AAEF,OAAO,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,CAAC"}