@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.
- package/dist/adapters/angular/angular-template-block-usage-utilities.d.ts +4 -0
- package/dist/adapters/angular/angular-template-block-usage-utilities.d.ts.map +1 -0
- package/dist/adapters/angular/angular-template-block-usage-utilities.js +69 -0
- package/dist/adapters/angular/angular-template-expression-utilities.d.ts +5 -0
- package/dist/adapters/angular/angular-template-expression-utilities.d.ts.map +1 -0
- package/dist/adapters/angular/angular-template-expression-utilities.js +121 -0
- package/dist/adapters/angular/angular-template-node-usage-utilities.d.ts +4 -0
- package/dist/adapters/angular/angular-template-node-usage-utilities.d.ts.map +1 -0
- package/dist/adapters/angular/angular-template-node-usage-utilities.js +47 -0
- package/dist/adapters/angular/angular-template-usage-context.d.ts +26 -0
- package/dist/adapters/angular/angular-template-usage-context.d.ts.map +1 -0
- package/dist/adapters/angular/angular-template-usage-context.js +12 -0
- package/dist/adapters/angular/index.d.ts +2 -0
- package/dist/adapters/angular/index.d.ts.map +1 -0
- package/dist/adapters/angular/index.js +2 -0
- package/dist/adapters/angular/no-unused-public-members-template-adapter.d.ts +15 -0
- package/dist/adapters/angular/no-unused-public-members-template-adapter.d.ts.map +1 -0
- package/dist/adapters/angular/no-unused-public-members-template-adapter.js +126 -0
- package/dist/adapters/angular/plugin.d.ts +12 -0
- package/dist/adapters/angular/plugin.d.ts.map +1 -0
- package/dist/adapters/angular/plugin.js +14 -0
- package/dist/adapters/index.d.ts +2 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +2 -0
- package/dist/application/custom-rules.d.ts +3 -0
- package/dist/application/custom-rules.d.ts.map +1 -1
- package/dist/application/custom-rules.js +3 -2
- package/dist/application/index.d.ts +1 -1
- package/dist/application/index.d.ts.map +1 -1
- package/dist/application/index.js +2 -2
- package/dist/codeperfect-eslint-plugin-1.0.0.tgz +0 -0
- package/dist/domain/architecture/consistent-barrel-files/barrel-file-utilities.d.ts +0 -2
- package/dist/domain/architecture/consistent-barrel-files/barrel-file-utilities.d.ts.map +1 -1
- package/dist/domain/architecture/consistent-barrel-files/barrel-file-utilities.js +1 -2
- package/dist/domain/architecture/consistent-barrel-files/consistent-barrel-files-options.d.ts +0 -2
- package/dist/domain/architecture/consistent-barrel-files/consistent-barrel-files-options.d.ts.map +1 -1
- package/dist/domain/architecture/consistent-barrel-files/consistent-barrel-files-options.js +2 -10
- package/dist/domain/architecture/index.d.ts +1 -0
- package/dist/domain/architecture/index.d.ts.map +1 -1
- package/dist/domain/architecture/index.js +2 -1
- package/dist/domain/architecture/no-unused-public-members/index.d.ts +2 -0
- package/dist/domain/architecture/no-unused-public-members/index.d.ts.map +1 -0
- package/dist/domain/architecture/no-unused-public-members/index.js +2 -0
- package/dist/domain/architecture/no-unused-public-members/member-contract-utilities.d.ts +16 -0
- package/dist/domain/architecture/no-unused-public-members/member-contract-utilities.d.ts.map +1 -0
- package/dist/domain/architecture/no-unused-public-members/member-contract-utilities.js +102 -0
- package/dist/domain/architecture/no-unused-public-members/member-declaration-utilities.d.ts +34 -0
- package/dist/domain/architecture/no-unused-public-members/member-declaration-utilities.d.ts.map +1 -0
- package/dist/domain/architecture/no-unused-public-members/member-declaration-utilities.js +55 -0
- package/dist/domain/architecture/no-unused-public-members/member-host-utilities.d.ts +68 -0
- package/dist/domain/architecture/no-unused-public-members/member-host-utilities.d.ts.map +1 -0
- package/dist/domain/architecture/no-unused-public-members/member-host-utilities.js +195 -0
- package/dist/domain/architecture/no-unused-public-members/member-public-api-utilities.d.ts +30 -0
- package/dist/domain/architecture/no-unused-public-members/member-public-api-utilities.d.ts.map +1 -0
- package/dist/domain/architecture/no-unused-public-members/member-public-api-utilities.js +106 -0
- package/dist/domain/architecture/no-unused-public-members/member-usage-expression-reference-utilities.d.ts +16 -0
- package/dist/domain/architecture/no-unused-public-members/member-usage-expression-reference-utilities.d.ts.map +1 -0
- package/dist/domain/architecture/no-unused-public-members/member-usage-expression-reference-utilities.js +77 -0
- package/dist/domain/architecture/no-unused-public-members/member-usage-handoff-utilities.d.ts +28 -0
- package/dist/domain/architecture/no-unused-public-members/member-usage-handoff-utilities.d.ts.map +1 -0
- package/dist/domain/architecture/no-unused-public-members/member-usage-handoff-utilities.js +151 -0
- package/dist/domain/architecture/no-unused-public-members/member-usage-local-flow-utilities.d.ts +16 -0
- package/dist/domain/architecture/no-unused-public-members/member-usage-local-flow-utilities.d.ts.map +1 -0
- package/dist/domain/architecture/no-unused-public-members/member-usage-local-flow-utilities.js +151 -0
- package/dist/domain/architecture/no-unused-public-members/member-usage-reference-utilities.d.ts +29 -0
- package/dist/domain/architecture/no-unused-public-members/member-usage-reference-utilities.d.ts.map +1 -0
- package/dist/domain/architecture/no-unused-public-members/member-usage-reference-utilities.js +115 -0
- package/dist/domain/architecture/no-unused-public-members/member-usage-serialization-utilities.d.ts +30 -0
- package/dist/domain/architecture/no-unused-public-members/member-usage-serialization-utilities.d.ts.map +1 -0
- package/dist/domain/architecture/no-unused-public-members/member-usage-serialization-utilities.js +107 -0
- package/dist/domain/architecture/no-unused-public-members/member-usage-type-utilities.d.ts +64 -0
- package/dist/domain/architecture/no-unused-public-members/member-usage-type-utilities.d.ts.map +1 -0
- package/dist/domain/architecture/no-unused-public-members/member-usage-type-utilities.js +152 -0
- package/dist/domain/architecture/no-unused-public-members/member-usage-utilities.d.ts +22 -0
- package/dist/domain/architecture/no-unused-public-members/member-usage-utilities.d.ts.map +1 -0
- package/dist/domain/architecture/no-unused-public-members/member-usage-utilities.js +137 -0
- package/dist/domain/architecture/no-unused-public-members/member-usage-value-utilities.d.ts +43 -0
- package/dist/domain/architecture/no-unused-public-members/member-usage-value-utilities.d.ts.map +1 -0
- package/dist/domain/architecture/no-unused-public-members/member-usage-value-utilities.js +126 -0
- package/dist/domain/architecture/no-unused-public-members/member-utilities.d.ts +43 -0
- package/dist/domain/architecture/no-unused-public-members/member-utilities.d.ts.map +1 -0
- package/dist/domain/architecture/no-unused-public-members/member-utilities.js +52 -0
- package/dist/domain/architecture/no-unused-public-members/rule.d.ts +16 -0
- package/dist/domain/architecture/no-unused-public-members/rule.d.ts.map +1 -0
- package/dist/domain/architecture/no-unused-public-members/rule.js +88 -0
- package/dist/domain/docs/no-interface-member-docs/comment-utilities.js +4 -4
- package/dist/domain/docs/no-interface-member-docs/parameter-tags.d.ts.map +1 -1
- package/dist/domain/docs/no-interface-member-docs/parameter-tags.js +2 -2
- package/dist/domain/docs/no-interface-member-docs/parameter-utilities.js +4 -4
- package/dist/domain/docs/no-interface-member-docs/rule.d.ts.map +1 -1
- package/dist/domain/docs/no-interface-member-docs/rule.js +2 -5
- package/dist/domain/docs/require-example-language/example-utilities.d.ts +1 -7
- package/dist/domain/docs/require-example-language/example-utilities.d.ts.map +1 -1
- package/dist/domain/docs/require-example-language/example-utilities.js +4 -6
- package/dist/domain/docs/require-example-language/examples.d.ts.map +1 -1
- package/dist/domain/docs/require-example-language/examples.js +2 -4
- package/dist/domain/docs/require-example-language/reporting.d.ts.map +1 -1
- package/dist/domain/docs/require-example-language/reporting.js +1 -4
- package/dist/domain/docs/require-example-language/types.d.ts +0 -2
- package/dist/domain/docs/require-example-language/types.d.ts.map +1 -1
- package/dist/domain/docs/require-example-language/types.js +1 -1
- package/dist/domain/index.d.ts +1 -1
- package/dist/domain/index.d.ts.map +1 -1
- package/dist/domain/index.js +2 -2
- package/dist/domain/testing/aaa/analyzer.analysis.d.ts.map +1 -1
- package/dist/domain/testing/aaa/analyzer.analysis.js +2 -7
- package/dist/domain/testing/aaa/analyzer.assertions.js +2 -2
- package/dist/domain/testing/aaa/analyzer.classification.js +2 -2
- package/dist/domain/testing/aaa/types.d.ts +0 -4
- package/dist/domain/testing/aaa/types.d.ts.map +1 -1
- package/dist/domain/testing/aaa/types.js +1 -1
- package/dist/domain/testing/enforce-aaa-phase-purity/pattern-identifiers.d.ts.map +1 -1
- package/dist/domain/testing/enforce-aaa-phase-purity/pattern-identifiers.js +2 -7
- package/dist/domain/testing/prefer-vi-mocked-import/match-bindings.d.ts.map +1 -1
- package/dist/domain/testing/prefer-vi-mocked-import/match-bindings.js +5 -9
- package/dist/domain/testing/prefer-vi-mocked-import/match-collisions.d.ts.map +1 -1
- package/dist/domain/testing/prefer-vi-mocked-import/match-collisions.js +2 -7
- package/dist/domain/testing/prefer-vi-mocked-import/match-declarations.d.ts.map +1 -1
- package/dist/domain/testing/prefer-vi-mocked-import/match-declarations.js +5 -5
- package/dist/domain/testing/prefer-vi-mocked-import/match-imports.d.ts.map +1 -1
- package/dist/domain/testing/prefer-vi-mocked-import/match-imports.js +13 -20
- package/dist/domain/testing/prefer-vi-mocked-import/types.d.ts +0 -2
- package/dist/domain/testing/prefer-vi-mocked-import/types.d.ts.map +1 -1
- package/dist/domain/testing/prefer-vi-mocked-import/types.js +1 -1
- package/dist/domain/testing/require-test-companion/require-test-companion-options.js +3 -3
- package/dist/domain/testing/require-test-companion/rule.js +2 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/infrastructure/codeperfect-plugin.d.ts +2 -0
- package/dist/infrastructure/codeperfect-plugin.d.ts.map +1 -1
- package/dist/infrastructure/codeperfect-plugin.js +3 -2
- package/dist/infrastructure/presets.d.ts.map +1 -1
- package/dist/infrastructure/presets.js +3 -1
- 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==
|
package/dist/domain/architecture/no-unused-public-members/member-usage-local-flow-utilities.d.ts
ADDED
|
@@ -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
|
package/dist/domain/architecture/no-unused-public-members/member-usage-local-flow-utilities.d.ts.map
ADDED
|
@@ -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"}
|
package/dist/domain/architecture/no-unused-public-members/member-usage-local-flow-utilities.js
ADDED
|
@@ -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
|
package/dist/domain/architecture/no-unused-public-members/member-usage-reference-utilities.d.ts
ADDED
|
@@ -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
|
package/dist/domain/architecture/no-unused-public-members/member-usage-reference-utilities.d.ts.map
ADDED
|
@@ -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==
|
package/dist/domain/architecture/no-unused-public-members/member-usage-serialization-utilities.d.ts
ADDED
|
@@ -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"}
|