fix(core): enforce optionality for API response fields in code_assist (#20714)

This commit is contained in:
Sehoon Shon
2026-03-03 11:17:34 -05:00
committed by GitHub
parent fca29b0bd8
commit aa158e18d3
2 changed files with 46 additions and 15 deletions
+35 -12
View File
@@ -25,6 +25,18 @@ const __dirname = path.dirname(__filename);
const projectRoot = __dirname; const projectRoot = __dirname;
const currentYear = new Date().getFullYear(); const currentYear = new Date().getFullYear();
const commonRestrictedSyntaxRules = [
{
selector: 'CallExpression[callee.name="require"]',
message: 'Avoid using require(). Use ES6 imports instead.',
},
{
selector: 'ThrowStatement > Literal:not([value=/^\\w+Error:/])',
message:
'Do not throw string literals or non-Error objects. Throw new Error("...") instead.',
},
];
export default tseslint.config( export default tseslint.config(
{ {
// Global ignores // Global ignores
@@ -120,18 +132,7 @@ export default tseslint.config(
'no-cond-assign': 'error', 'no-cond-assign': 'error',
'no-debugger': 'error', 'no-debugger': 'error',
'no-duplicate-case': 'error', 'no-duplicate-case': 'error',
'no-restricted-syntax': [ 'no-restricted-syntax': ['error', ...commonRestrictedSyntaxRules],
'error',
{
selector: 'CallExpression[callee.name="require"]',
message: 'Avoid using require(). Use ES6 imports instead.',
},
{
selector: 'ThrowStatement > Literal:not([value=/^\\w+Error:/])',
message:
'Do not throw string literals or non-Error objects. Throw new Error("...") instead.',
},
],
'no-unsafe-finally': 'error', 'no-unsafe-finally': 'error',
'no-unused-expressions': 'off', // Disable base rule 'no-unused-expressions': 'off', // Disable base rule
'@typescript-eslint/no-unused-expressions': [ '@typescript-eslint/no-unused-expressions': [
@@ -171,6 +172,28 @@ export default tseslint.config(
], ],
}, },
}, },
{
// API Response Optionality enforcement for Code Assist
files: ['packages/core/src/code_assist/**/*.{ts,tsx}'],
rules: {
'no-restricted-syntax': [
'error',
...commonRestrictedSyntaxRules,
{
selector:
'TSInterfaceDeclaration[id.name=/.+Response$/] TSPropertySignature:not([optional=true])',
message:
'All fields in API response interfaces (*Response) must be marked as optional (?) to prevent developers from accidentally assuming a field will always be present based on current backend behavior.',
},
{
selector:
'TSTypeAliasDeclaration[id.name=/.+Response$/] TSPropertySignature:not([optional=true])',
message:
'All fields in API response types (*Response) must be marked as optional (?) to prevent developers from accidentally assuming a field will always be present based on current backend behavior.',
},
],
},
},
{ {
// Rules that only apply to product code // Rules that only apply to product code
files: ['packages/*/src/**/*.{ts,tsx}'], files: ['packages/*/src/**/*.{ts,tsx}'],
+11 -3
View File
@@ -508,6 +508,16 @@ export class CodeAssistServer implements ContentGenerator {
} }
interface VpcScErrorResponse { interface VpcScErrorResponse {
response?: {
data?: {
error?: {
details?: unknown[];
};
};
};
}
function isVpcScErrorResponse(error: unknown): error is VpcScErrorResponse & {
response: { response: {
data: { data: {
error: { error: {
@@ -515,9 +525,7 @@ interface VpcScErrorResponse {
}; };
}; };
}; };
} } {
function isVpcScErrorResponse(error: unknown): error is VpcScErrorResponse {
return ( return (
!!error && !!error &&
typeof error === 'object' && typeof error === 'object' &&