From 33b0a9c7b89d6ace7a81a2e1817422cf4033288c Mon Sep 17 00:00:00 2001 From: Khaliq Date: Thu, 19 Sep 2024 16:11:34 +0300 Subject: [PATCH 1/5] [nan-1752] add tests --- .github/workflows/tests.yaml | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 .github/workflows/tests.yaml diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml new file mode 100644 index 0000000..5169f43 --- /dev/null +++ b/.github/workflows/tests.yaml @@ -0,0 +1,32 @@ +name: Run Tests + +on: + push: + branches: + - main + pull_request: + +concurrency: + group: tests-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + tests: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] + node-version: [18.x, 20.x] + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: '0' + + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + cache: 'npm' + node-version: ${{ matrix.node-version }} + + - run: npm run test From d79d94f26c02d4a9cb04e21cdeac083a1472f5e4 Mon Sep 17 00:00:00 2001 From: Khaliq Date: Thu, 19 Sep 2024 16:12:53 +0300 Subject: [PATCH 2/5] [nan-1752] npm ci --- .github/workflows/tests.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 5169f43..5e7b971 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -29,4 +29,5 @@ jobs: cache: 'npm' node-version: ${{ matrix.node-version }} + - run: npm ci - run: npm run test From cff3c83b7a89a383ab2455607a82c201cb25b7a6 Mon Sep 17 00:00:00 2001 From: Khaliq Date: Thu, 19 Sep 2024 16:57:01 +0300 Subject: [PATCH 3/5] [nan-1752]] fix tests --- src/rules/proxy-call-retries.test.ts | 193 ++++++++++++--------------- src/rules/proxy-call-retries.ts | 134 ++++++++++--------- 2 files changed, 153 insertions(+), 174 deletions(-) diff --git a/src/rules/proxy-call-retries.test.ts b/src/rules/proxy-call-retries.test.ts index 958fc26..6ffb230 100644 --- a/src/rules/proxy-call-retries.test.ts +++ b/src/rules/proxy-call-retries.test.ts @@ -3,120 +3,97 @@ import { describe, it } from 'vitest'; import proxyCallRetries from './proxy-call-retries'; const ruleTester = new RuleTester({ - parser: require.resolve('@typescript-eslint/parser'), - parserOptions: { ecmaVersion: 2018, sourceType: 'module' }, + parser: require.resolve('@typescript-eslint/parser'), + parserOptions: { ecmaVersion: 2018, sourceType: 'module' }, }); describe('proxy-call-retries', () => { - it('should pass valid cases and fail invalid cases', () => { - ruleTester.run('proxy-call-retries', proxyCallRetries, { - valid: [ - { code: "await nango.get({ retries: 10 })", name: "Simple get with retries" }, - { code: "await nango.put({ retries: 10 })", name: "Simple put with retries" }, - { code: "await nango.patch({ retries: 10 })", name: "Simple patch with retries" }, - { code: "await nango.delete({ retries: 10 })", name: "Simple delete with retries" }, - { code: "await nango.proxy({ method: 'GET', retries: 10 })", name: "Proxy with retries" }, - { - code: ` - const config = { - endpoint: 'api.xro/2.0/Contacts', - headers: { 'xero-tenant-id': tenant_id }, - params: { summarizeErrors: 'false' }, - retries: 10, - data: { Contacts: input.map(toXeroContact) } - }; - const res = await nango.post(config); - `, - name: "Config object with retries" - }, - { - code: `const res = await nango.get({ endpoint: 'api.example.com', retries: 5 });`, - name: "Inline object with retries" - }, - { - code: ` - const config = { endpoint: 'api.example.com', retries: 3 }; - const res = await nango.put(config); - `, - name: "Simple config object with retries" - }, - { - code: ` - const retries = 3; + it('should pass valid cases and fail invalid cases', () => { + ruleTester.run('proxy-call-retries', proxyCallRetries, { + valid: [ + { code: "await nango.get({ retries: 10 })", name: "Simple get with retries" }, + { code: "await nango.put({ retries: 10 })", name: "Simple put with retries" }, + { code: "await nango.patch({ retries: 10 })", name: "Simple patch with retries" }, + { code: "await nango.delete({ retries: 10 })", name: "Simple delete with retries" }, + { code: "await nango.proxy({ method: 'GET', retries: 10 })", name: "Proxy with retries" }, + { + code: ` + const config = { + endpoint: 'api.xro/2.0/Contacts', + headers: { 'xero-tenant-id': tenant_id }, + params: { summarizeErrors: 'false' }, + retries: 10, + data: { Contacts: input.map(toXeroContact) } + }; + const res = await nango.post(config); + `, + name: "Config object with retries" + }, + { + code: `const res = await nango.get({ endpoint: 'api.example.com', retries: 5 });`, + name: "Inline object with retries" + }, + { + code: ` + const config = { endpoint: 'api.example.com', retries: 3 }; + const res = await nango.put(config); + `, + name: "Simple config object with retries" + }, + { + code: ` + const retries = 3; - export default async function fetchData(nango: NangoSync): Promise { - const proxyConfig: ProxyConfiguration = { - endpoint: '/customerpayment', - retries - }; - for await (const payments of paginate<{ id: string }>({ nango, proxyConfig })) { - await nango.log('Listed payments', { total: payments.length }); - - const mappedPayments: NetsuitePayment[] = []; - for (const paymentLink of payments) { - const payment: NSAPI_GetResponse = await nango.get({ - endpoint: \`/customerpayment/\${paymentLink.id}\`, - params: { - expandSubResources: 'true' - }, + export default async function fetchData(nango: NangoSync): Promise { + const proxyConfig: ProxyConfiguration = { + endpoint: '/customerpayment', retries - }); + }; + for await (const payments of paginate<{ id: string }>({ nango, proxyConfig })) { + await nango.log('Listed payments', { total: payments.length }); + + const mappedPayments: NetsuitePayment[] = []; + for (const paymentLink of payments) { + const payment: NSAPI_GetResponse = await nango.get({ + endpoint: \`/customerpayment/\${paymentLink.id}\`, + params: { + expandSubResources: 'true' + }, + retries + }); + } + } } + `, + name: "Variable retries in config and nango.get" + }, + ], + invalid: [ + { + code: "await nango.get({})", + errors: [{ message: 'Nango API calls should include a retries property in the options object' }], + output: "await nango.get({ retries: 10 })", + name: "Empty object without retries" + }, + { + code: "await nango.post({ retries: '10' })", + errors: [{ message: 'The retries property should be an integer value' }], + output: "await nango.post({ retries: 10 })", + name: "String retries value" + }, + { + code: "await nango.put({ retries: 10.5 })", + errors: [{ message: 'The retries property should be an integer value' }], + output: "await nango.put({ retries: 10 })", + name: "Float retries value" + }, + { + code: "await nango.patch()", + errors: [{ message: 'Nango API calls should include an options object with a retries property' }], + output: "await nango.patch({ retries: 10 })", + name: "No options object" } - } - `, - name: "Variable retries in config and nango.get" - }, - ], - invalid: [ - { - code: "await nango.get({})", - errors: [{ message: 'Nango API calls should include a retries property in the options object' }], - output: "await nango.get({ retries: 10 })", - name: "Empty object without retries" - }, - { - code: "await nango.post({ retries: '10' })", - errors: [{ message: 'The retries property should be an integer value' }], - output: "await nango.post({ retries: 10 })", - name: "String retries value" - }, - { - code: "await nango.put({ retries: 10.5 })", - errors: [{ message: 'The retries property should be an integer value' }], - output: "await nango.put({ retries: 10 })", - name: "Float retries value" - }, - { - code: "await nango.patch()", - errors: [{ message: 'Nango API calls should include an options object with a retries property' }], - output: "await nango.patch({ retries: 10 })", - name: "No options object" - }, - { - code: ` - const config = { - endpoint: 'api.xro/2.0/Contacts', - headers: { 'xero-tenant-id': tenant_id }, - params: { summarizeErrors: 'false' }, - data: { Contacts: input.map(toXeroContact) } - }; - const res = await nango.post(config); - `, - errors: [{ message: 'Nango API calls should include a retries property in the options object' }], - output: ` - const config = { - endpoint: 'api.xro/2.0/Contacts', - headers: { 'xero-tenant-id': tenant_id }, - params: { summarizeErrors: 'false' }, - data: { Contacts: input.map(toXeroContact) }, - retries: 10 - }; - const res = await nango.post(config); - `, - name: "Config object without retries" - }, - ], + ], + }); }); - }); }); diff --git a/src/rules/proxy-call-retries.ts b/src/rules/proxy-call-retries.ts index c468fbe..76b40f6 100644 --- a/src/rules/proxy-call-retries.ts +++ b/src/rules/proxy-call-retries.ts @@ -1,5 +1,5 @@ import { Rule } from 'eslint'; -import { Node, CallExpression, ObjectExpression, Property, Identifier } from 'estree'; +import { Node, CallExpression, ObjectExpression, Property, Identifier, VariableDeclarator } from 'estree'; const proxyCallRetries: Rule.RuleModule = { meta: { @@ -13,77 +13,31 @@ const proxyCallRetries: Rule.RuleModule = { schema: [], }, create(context: Rule.RuleContext) { + const configObjects: { [key: string]: ObjectExpression } = {}; + return { + VariableDeclarator(node: Node) { + if (node.type === 'VariableDeclarator' && node.init && node.init.type === 'ObjectExpression') { + if (node.id.type === 'Identifier') { + configObjects[node.id.name] = node.init; + } + } + }, CallExpression(node: Node) { if (isNangoApiCall(node)) { if (node.arguments.length === 0) { - context.report({ - node, - message: 'Nango API calls should include an options object with a retries property', - fix(fixer) { - // @ts-ignore - return fixer.replaceText(node, `nango.${node.callee.property.name}({ retries: 10 })`); - } - }); + reportMissingRetries(context, node); return; } const options = node.arguments[0]; - - if (!options) { - context.report({ - node, - message: 'Nango API calls should include an options object with a retries property', - fix(fixer) { - return fixer.insertTextAfter(node.callee, '({ retries: 10 })'); - } - }); - return; - } - - if (options.type === 'Identifier') { - // If the options is a variable, we need to check its declaration - const variable = context.getScope().variables.find(v => v.name === options.name); - if (variable && variable.defs[0] && variable.defs[0].node.type === 'VariableDeclarator') { - const declarator = variable.defs[0].node; - if (declarator.init && declarator.init.type === 'ObjectExpression') { - const retriesProperty = declarator.init.properties.find(isRetriesProperty); - if (retriesProperty && isValidRetriesValue(retriesProperty)) { - return; // Valid case, no need to report - } - } - } - // If we can't determine the content of the variable, we don't report an error - return; - } - if (options.type !== 'ObjectExpression') { - return; // We can't determine the content, so we don't report an error - } - - const retriesProperty = options.properties.find(isRetriesProperty); - - if (!retriesProperty) { - context.report({ - node: options, - message: 'Nango API calls should include a retries property in the options object', - fix(fixer) { - if (options.properties.length === 0) { - return fixer.replaceText(options, '{ retries: 10 }'); - } else { - const lastProperty = options.properties[options.properties.length - 1]; - return fixer.insertTextAfter(lastProperty, ', retries: 10'); - } - } - }); - } else if (!isValidRetriesValue(retriesProperty)) { - context.report({ - node: retriesProperty, - message: 'The retries property should be an integer value', - fix(fixer) { - return fixer.replaceText(retriesProperty.value, '10'); - } - }); + if (options.type === 'Identifier' && configObjects[options.name]) { + checkConfigObject(context, configObjects[options.name], options); + } else if (options.type === 'ObjectExpression') { + checkConfigObject(context, options, options); + } else { + reportMissingRetries(context, node); } } }, @@ -91,6 +45,52 @@ const proxyCallRetries: Rule.RuleModule = { }, }; +function checkConfigObject(context: Rule.RuleContext, configObject: ObjectExpression, reportNode: Node) { + const retriesProperty = configObject.properties.find(isRetriesProperty); + + if (!retriesProperty) { + context.report({ + node: reportNode, + message: 'Nango API calls should include a retries property in the options object', + fix(fixer) { + if (configObject.properties.length === 0) { + return fixer.replaceText(configObject, '{ retries: 10 }'); + } else { + const sourceCode = context.getSourceCode(); + const lastProperty = configObject.properties[configObject.properties.length - 1]; + const lastPropertyText = sourceCode.getText(lastProperty); + const lastPropertyLines = lastPropertyText.split('\n'); + const [lastPropertyIndentation] = lastPropertyLines; + const indentation = lastPropertyIndentation.match(/^\s*/)![0]; + return fixer.insertTextAfter(lastProperty, `,\n${indentation}retries: 10`); + } + } + }); + } else if (retriesProperty.value.type === 'Literal' && !isValidRetriesValue(retriesProperty)) { + context.report({ + node: retriesProperty, + message: 'The retries property should be an integer value', + fix(fixer) { + return fixer.replaceText(retriesProperty.value, '10'); + } + }); + } +} + +function reportMissingRetries(context: Rule.RuleContext, node: Node) { + if (node.type !== 'CallExpression') { + return; // This should never happen, but it satisfies TypeScript + } + + context.report({ + node, + message: 'Nango API calls should include an options object with a retries property', + fix(fixer) { + return fixer.replaceText(node, `${context.getSourceCode().getText(node.callee)}({ retries: 10 })`); + } + }); +} + function isNangoApiCall(node: Node): node is CallExpression { return ( node.type === 'CallExpression' && @@ -111,9 +111,11 @@ function isRetriesProperty(prop: Node): prop is Property { } function isValidRetriesValue(prop: Property): boolean { - if (prop.value.type !== 'Literal') return false; - const value = prop.value.value; - return typeof value === 'number' && Number.isInteger(value) && value > 0; + if (prop.value.type === 'Literal') { + const value = prop.value.value; + return typeof value === 'number' && Number.isInteger(value) && value > 0; + } + return false; } export default proxyCallRetries; From 232332a0ee5ec70ff2e5f4924ee56ba80430ac43 Mon Sep 17 00:00:00 2001 From: Khaliq Date: Thu, 19 Sep 2024 17:28:44 +0300 Subject: [PATCH 4/5] [nan-1752] add enforce proxy configuration logic --- .../enforce-proxy-configuration-type.test.ts | 149 ++++++------------ src/rules/enforce-proxy-configuration-type.ts | 113 ++++++------- 2 files changed, 104 insertions(+), 158 deletions(-) diff --git a/src/rules/enforce-proxy-configuration-type.test.ts b/src/rules/enforce-proxy-configuration-type.test.ts index 10227bf..c94a31c 100644 --- a/src/rules/enforce-proxy-configuration-type.test.ts +++ b/src/rules/enforce-proxy-configuration-type.test.ts @@ -3,111 +3,52 @@ import { describe, it } from 'vitest'; import enforceProxyConfigurationType from './enforce-proxy-configuration-type'; const ruleTester = new RuleTester({ - parser: require.resolve('@typescript-eslint/parser'), - parserOptions: { - ecmaVersion: 2018, - sourceType: 'module', - }, + parser: require.resolve('@typescript-eslint/parser'), + parserOptions: { ecmaVersion: 2018, sourceType: 'module' }, }); -describe('enforce-proxy-configuration-type', () => { - it('should pass valid cases and fail invalid cases', () => { - ruleTester.run('enforce-proxy-configuration-type', enforceProxyConfigurationType, { - valid: [ - { - code: ` - const config: ProxyConfiguration = { - endpoint: 'api.xro/2.0/Contacts', - headers: { 'xero-tenant-id': tenant_id }, - params: { summarizeErrors: 'false' }, - data: { Contacts: input.map(toXeroContact) } - }; - const res = await nango.post(config); - `, - }, - { - code: ` - let config: ProxyConfiguration; - config = { - endpoint: 'api.xro/2.0/Contacts', - headers: { 'xero-tenant-id': tenant_id }, - params: { summarizeErrors: 'false' }, - data: { Contacts: input.map(toXeroContact) } - }; - const res = await nango.get(config); - `, - }, - { - code: ` - const res = await nango.put({ endpoint: 'api.example.com', data: {} }); - `, - }, - ], - invalid: [ - { - code: ` - const config = { - endpoint: 'api.xro/2.0/Contacts', - headers: { 'xero-tenant-id': tenant_id }, - params: { summarizeErrors: 'false' }, - data: { Contacts: input.map(toXeroContact) } - }; - const res = await nango.post(config); - `, - errors: [{ message: 'Configuration object for Nango API calls should be typed as ProxyConfiguration' }], - output: ` - const config: ProxyConfiguration = { - endpoint: 'api.xro/2.0/Contacts', - headers: { 'xero-tenant-id': tenant_id }, - params: { summarizeErrors: 'false' }, - data: { Contacts: input.map(toXeroContact) } - }; - const res = await nango.post(config); - `, - }, - { - code: ` - let config = { - endpoint: 'api.xro/2.0/Contacts', - headers: { 'xero-tenant-id': tenant_id }, - params: { summarizeErrors: 'false' }, - data: { Contacts: input.map(toXeroContact) } - }; - const res = await nango.get(config); - `, - errors: [{ message: 'Configuration object for Nango API calls should be typed as ProxyConfiguration' }], - output: ` - let config: ProxyConfiguration = { - endpoint: 'api.xro/2.0/Contacts', - headers: { 'xero-tenant-id': tenant_id }, - params: { summarizeErrors: 'false' }, - data: { Contacts: input.map(toXeroContact) } - }; - const res = await nango.get(config); - `, - }, - { - code: ` - var config = { - endpoint: 'api.xro/2.0/Contacts', - headers: { 'xero-tenant-id': tenant_id }, - params: { summarizeErrors: 'false' }, - data: { Contacts: input.map(toXeroContact) } - }; - const res = await nango.proxy(config); - `, - errors: [{ message: 'Configuration object for Nango API calls should be typed as ProxyConfiguration' }], - output: ` - var config: ProxyConfiguration = { - endpoint: 'api.xro/2.0/Contacts', - headers: { 'xero-tenant-id': tenant_id }, - params: { summarizeErrors: 'false' }, - data: { Contacts: input.map(toXeroContact) } - }; - const res = await nango.proxy(config); - `, - }, - ], +describe('enforce-proxy-configuration-type-tests', () => { + it('should pass valid cases and fail invalid cases', () => { + ruleTester.run('enforce-proxy-configuration-type', enforceProxyConfigurationType, { + valid: [ + { + code: ` + import type { NangoSync, Account, ProxyConfiguration } from '../../models'; + const config: ProxyConfiguration = { + endpoint: 'api.xro/2.0/Accounts', + headers: { 'xero-tenant-id': tenant_id }, + params: { order: 'UpdatedDateUTC DESC' }, + retries: 10 + }; + `, + }, + ], + invalid: [ + { + code: ` + import type { NangoSync, Account } from '../../models'; + const config = { + endpoint: 'api.xro/2.0/Accounts', + headers: { 'xero-tenant-id': tenant_id }, + params: { order: 'UpdatedDateUTC DESC' }, + retries: 10 + }; + `, + errors: [ + { message: 'ProxyConfiguration type should be imported from ../../models' }, + { message: 'ProxyConfiguration type should be used for Nango API call configurations' }, + ], + output: ` + import type { NangoSync, Account, ProxyConfiguration } from '../../models'; + const config: ProxyConfiguration = { + endpoint: 'api.xro/2.0/Accounts', + headers: { 'xero-tenant-id': tenant_id }, + params: { order: 'UpdatedDateUTC DESC' }, + retries: 10 + }; + `, + }, + ], + }); }); - }); }); diff --git a/src/rules/enforce-proxy-configuration-type.ts b/src/rules/enforce-proxy-configuration-type.ts index 14f45a8..2042369 100644 --- a/src/rules/enforce-proxy-configuration-type.ts +++ b/src/rules/enforce-proxy-configuration-type.ts @@ -1,5 +1,5 @@ import { Rule } from 'eslint'; -import { Node, CallExpression, Identifier, VariableDeclarator } from 'estree'; +import { ImportDeclaration, VariableDeclaration, VariableDeclarator, Identifier, ObjectExpression, Property } from 'estree'; const enforceProxyConfigurationType: Rule.RuleModule = { meta: { @@ -12,66 +12,71 @@ const enforceProxyConfigurationType: Rule.RuleModule = { fixable: 'code', schema: [], }, - create(context: Rule.RuleContext) { - const sourceCode = context.getSourceCode(); + create(context) { + let hasProxyConfigurationImport = false; + let configVariableName: string | null = null; + let importNode: ImportDeclaration | null = null; + let configNode: VariableDeclaration | null = null; return { - CallExpression(node: Node) { - if (isNangoApiCall(node)) { - const options = node.arguments[0]; - - if (options && options.type === 'Identifier') { - const scope = sourceCode.getScope(node); - const variable = scope.variables.find(v => v.name === options.name); - if (variable && variable.defs[0] && variable.defs[0].node.type === 'VariableDeclarator') { - const declarator = variable.defs[0].node; - if (!hasProxyConfigurationType(declarator, context)) { - context.report({ - node: declarator, - message: 'Configuration object for Nango API calls should be typed as ProxyConfiguration', - fix(fixer) { - const declarationToken = sourceCode.getFirstToken(declarator.parent); - if (declarationToken && (declarationToken.value === 'const' || declarationToken.value === 'let' || declarationToken.value === 'var')) { - return fixer.insertTextAfter(declarator.id, ': ProxyConfiguration'); - } - return null; - } - }); - } - } + ImportDeclaration(node: ImportDeclaration) { + if (node.source.value === '../../models') { + importNode = node; + hasProxyConfigurationImport = node.specifiers.some( + (specifier) => specifier.type === 'ImportSpecifier' && + 'imported' in specifier && + specifier.imported.type === 'Identifier' && + specifier.imported.name === 'ProxyConfiguration' + ); + } + }, + VariableDeclaration(node: VariableDeclaration) { + const declarator = node.declarations[0] as VariableDeclarator; + if (declarator && declarator.type === 'VariableDeclarator' && + declarator.id.type === 'Identifier' && declarator.init && + declarator.init.type === 'ObjectExpression') { + const properties = declarator.init.properties; + if (properties.some((prop): prop is Property => + prop.type === 'Property' && + prop.key.type === 'Identifier' && + prop.key.name === 'endpoint')) { + configVariableName = declarator.id.name; + configNode = node; } } }, - }; - }, -}; - -function isNangoApiCall(node: Node): node is CallExpression { - return ( - node.type === 'CallExpression' && - node.callee.type === 'MemberExpression' && - node.callee.object.type === 'Identifier' && - node.callee.object.name === 'nango' && - node.callee.property.type === 'Identifier' && - ['get', 'post', 'put', 'patch', 'delete', 'proxy'].includes(node.callee.property.name) - ); -} + 'Program:exit'() { + if (configVariableName && !hasProxyConfigurationImport && importNode && configNode) { + context.report({ + node: context.getSourceCode().ast, + message: 'ProxyConfiguration type should be imported and used for Nango API call configurations', + fix(fixer) { + const fixes = []; -function hasProxyConfigurationType(node: VariableDeclarator, context: Rule.RuleContext): boolean { - const sourceCode = context.getSourceCode(); - const idToken = sourceCode.getFirstToken(node.id); - if (!idToken) return false; + if (importNode && importNode.specifiers.length > 0) { + fixes.push(fixer.insertTextAfter( + importNode.specifiers[importNode.specifiers.length - 1], + ', ProxyConfiguration' + )); + } - const nextToken = sourceCode.getTokenAfter(idToken); - if (!nextToken) return false; + if (configNode && configNode.declarations.length > 0) { + const configDeclarator = configNode.declarations[0] as VariableDeclarator; + if (configDeclarator && configDeclarator.id.type === 'Identifier') { + fixes.push(fixer.insertTextAfter( + configDeclarator.id, + ': ProxyConfiguration' + )); + } + } - const tokenAfterColon = sourceCode.getTokenAfter(nextToken); - - return ( - nextToken.type === 'Punctuator' && - nextToken.value === ':' && - tokenAfterColon?.value === 'ProxyConfiguration' - ); -} + return fixes; + }, + }); + } + }, + }; + }, +}; export default enforceProxyConfigurationType; From aa311ace05afaaf53fbd4286e33a4c322a83c7ab Mon Sep 17 00:00:00 2001 From: Khaliq Date: Thu, 19 Sep 2024 17:34:24 +0300 Subject: [PATCH 5/5] [nan-1752] fix test --- src/rules/enforce-proxy-configuration-type.test.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/rules/enforce-proxy-configuration-type.test.ts b/src/rules/enforce-proxy-configuration-type.test.ts index c94a31c..1dbde69 100644 --- a/src/rules/enforce-proxy-configuration-type.test.ts +++ b/src/rules/enforce-proxy-configuration-type.test.ts @@ -35,8 +35,7 @@ describe('enforce-proxy-configuration-type-tests', () => { }; `, errors: [ - { message: 'ProxyConfiguration type should be imported from ../../models' }, - { message: 'ProxyConfiguration type should be used for Nango API call configurations' }, + { message: 'ProxyConfiguration type should be imported and used for Nango API call configurations' }, ], output: ` import type { NangoSync, Account, ProxyConfiguration } from '../../models';