Skip to content

Commit

Permalink
fix(providers): improve validation for connect (#3109)
Browse files Browse the repository at this point in the history
## Changes

Improve validation for providers
- Detect invalid path
- Detect missing doc_connect
- Detect invalid doc_section
  • Loading branch information
bodinsamuel authored Dec 4, 2024
1 parent 7b0a7c2 commit cf6cd57
Show file tree
Hide file tree
Showing 12 changed files with 71 additions and 15 deletions.
6 changes: 2 additions & 4 deletions .github/workflows/validation.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,9 @@ jobs:
node-version-file: '.nvmrc'
registry-url: 'https://registry.npmjs.org'

- run: npm ci
- name: Validate YAML
run: |
npm ci
npx tsx scripts/validation/providers/validate.ts
run: npm run test:providers

- name: Validate OpenAPI
run: npm run test:openapi
File renamed without changes.
File renamed without changes.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"test:integration": "vitest --config ./vite.integration.config.ts",
"test:cli": "vitest --config ./vite.cli.config.ts",
"test:openapi": "npx @apidevtools/swagger-cli validate docs-v2/spec.yaml",
"test:providers": "npx tsx scripts/validation/providers/validate.ts",
"docs": "cd ./docs-v2 && npx mintlify dev --port 3033",
"nango": "cd ./packages/server && npm run nango",
"dev:docker": "docker compose --file dev/docker-compose.dev.yaml up -d"
Expand Down
4 changes: 1 addition & 3 deletions packages/shared/providers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -746,7 +746,7 @@ bill-sandbox:
proxy:
base_url: https://gateway.stage.bill.com/connect
docs: https://docs.nango.dev/integrations/all/bill
docs_connect: https://docs.nango.dev/integrations/all/bill/connect
docs_connect: https://docs.nango.dev/integrations/all/bill-sandbox/connect

bill:
display_name: Bill (Connect API)
Expand Down Expand Up @@ -5995,7 +5995,6 @@ trello-scim:
headers:
Authorization: Bearer ${apiKey}
docs: https://docs.nango.dev/integrations/all/trello
docs_connect: https://docs.nango.dev/integrations/all/trello-scim/connect
credentials:
apiKey:
type: string
Expand Down Expand Up @@ -6299,7 +6298,6 @@ unipile:
headers:
x-api-key: ${apiKey}
docs: https://docs.nango.dev/integrations/all/unipile
docs_connect: https://docs.nango.dev/integrations/all/unipile/connect
credentials:
apiKey:
type: string
Expand Down
75 changes: 67 additions & 8 deletions scripts/validation/providers/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,12 @@ console.log('✅ All providers are valid');
* Validate one provider
*/
function validateProvider(providerKey: string, provider: Provider) {
const filename = provider.docs.split('/').slice(-1)[0];
const filename = provider.docs.split('/').slice(-1)[0]; // filename could be different from providerConfigKey
const mdx = path.join(docsPath, `${filename}.mdx`);
const svg = path.join(svgPath, `${providerKey}.svg`);
const connectMdx = path.join(docsPath, `${providerKey}/connect.mdx`);
let hasValidConnect = false;
const headers = new Set<string>();

if (!fs.existsSync(mdx)) {
console.error(chalk.red('error'), chalk.blue(providerKey), `Documentation file not found`);
Expand All @@ -96,6 +99,26 @@ function validateProvider(providerKey: string, provider: Provider) {
console.error(`Expected file: ${svg}`);
error = true;
}
if (provider.docs_connect) {
if (!fs.existsSync(connectMdx)) {
console.error(chalk.red('error'), chalk.blue(providerKey), `Connect.mdx file not found`);
console.error(`Expected file: ${connectMdx}`);
error = true;
} else {
hasValidConnect = true;
const content = fs.readFileSync(connectMdx).toString();
const matched = content.matchAll(/^[#]+\sStep[a-zA-Z0-9:()._ -]+$/gim);
for (const match of matched) {
headers.add(
match[0]
.toLocaleLowerCase()
.replace(/^[#]+ /, '#')
.replaceAll(/\s/g, '-')
.replaceAll(/[:()._]/g, '')
);
}
}
}

// Find all connectionConfig references
const connectionConfigReferences = findConnectionConfigReferences(provider);
Expand All @@ -116,14 +139,50 @@ function validateProvider(providerKey: string, provider: Provider) {
continue;
}
}

// Check connection config validity
for (const [key, schema] of Object.entries(provider.connection_config || [])) {
if (schema.doc_section && !provider.docs_connect) {
console.error(
chalk.red('error'),
chalk.blue(providerKey),
`"connection_config > ${key}" defines a "doc_section" but has no "docs_connect" property`
);
error = true;
if (schema.doc_section) {
if (!provider.docs_connect) {
console.error(
chalk.red('error'),
chalk.blue(providerKey),
`"connection_config > ${key}" defines a "doc_section" but has no "docs_connect" property`
);
error = true;
} else if (hasValidConnect) {
if (!headers.has(schema.doc_section)) {
console.error(
chalk.red('error'),
chalk.blue(providerKey),
`"connection_config > ${key} > doc_section" does not exist in ${providerKey}/connect.mdx`
);
error = true;
}
}
}
}

// Check credentials validity
for (const [key, schema] of Object.entries(provider.credentials || [])) {
if (schema.doc_section) {
if (!provider.docs_connect) {
console.error(
chalk.red('error'),
chalk.blue(providerKey),
`"credentials > ${key}" defines a "doc_section" but has no "docs_connect" property`
);
error = true;
} else if (hasValidConnect) {
if (!headers.has(schema.doc_section)) {
console.error(
chalk.red('error'),
chalk.blue(providerKey),
`"credentials > ${key} > doc_section" does not exist in ${providerKey}/connect.mdx`
);
error = true;
}
}
}
}
} else if (provider.connection_config) {
Expand Down

0 comments on commit cf6cd57

Please sign in to comment.