feat(integrations): add Cloud SQL integration support#432
Conversation
Bump @deepnote/database-integrations from 1.4.3 to 1.5.0, which adds the
`cloud-sql` database integration type, and wire it through the extension
following the convention used by the other integrations:
- Add Cloud SQL to the type-label and icon maps (incl. new cloud-sql.svg)
- Add CloudSqlForm (name + service account JSON, matching the
`{ service_account }` metadata schema) and route to it from
ConfigurationForm
- Surface Cloud SQL in the integration type selector and item label
- Add the corresponding localization keys, strings and webview wiring
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019VuoSZXF8YHsN81Lra45JW
📝 WalkthroughWalkthroughAdds Google Cloud SQL as a supported database integration. The dependency on Sequence Diagram(s)sequenceDiagram
participant localize as localize.ts
participant integrationWebview as integrationWebview.ts
participant CloudSqlForm as CloudSqlForm.tsx
participant validateServiceAccountJson as validateServiceAccountJson
localize->>integrationWebview: provide Cloud SQL strings
integrationWebview->>CloudSqlForm: send localized form text
CloudSqlForm->>validateServiceAccountJson: validate service_account JSON
validateServiceAccountJson-->>CloudSqlForm: required or invalid-json result
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested reviewers
🚥 Pre-merge checks | ✅ 5 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (5 passed)
Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #432 +/- ##
===========================
===========================
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/webviews/webview-side/integrations/CloudSqlForm.tsx`:
- Around line 42-48: The CloudSqlForm state reset in the React.useEffect that
updates pendingConfig should also clear serviceAccountError when existingConfig,
integrationId, or defaultName changes. Update the same effect in CloudSqlForm so
switching integrations or reloading a valid config resets the validation state
and does not leave a stale error blocking Save.
- Around line 73-88: The Cloud SQL submit path in handleSubmit currently only
trims for JSON parsing, so whitespace-only service_account values can still
reach onSave as if they were valid. Update CloudSqlForm.tsx to treat
pendingConfig.metadata.service_account as missing when trim() is empty, set the
same service account validation error, and return before calling onSave. Make
the same check anywhere else in this flow that relies on service_account being
required so the form cannot persist an effectively blank credential.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: b63e8317-921f-49ef-9372-0ca68aaf1596
⛔ Files ignored due to path filters (2)
package-lock.jsonis excluded by!**/package-lock.jsonsrc/webviews/webview-side/integrations/icons/cloud-sql.svgis excluded by!**/*.svg
📒 Files selected for processing (10)
package.jsonsrc/messageTypes.tssrc/notebooks/deepnote/integrations/integrationWebview.tssrc/notebooks/deepnote/sqlCellStatusBarProvider.tssrc/platform/common/utils/localize.tssrc/webviews/webview-side/integrations/CloudSqlForm.tsxsrc/webviews/webview-side/integrations/ConfigurationForm.tsxsrc/webviews/webview-side/integrations/IntegrationItem.tsxsrc/webviews/webview-side/integrations/IntegrationTypeSelector.tsxsrc/webviews/webview-side/integrations/integrationUtils.ts
…anner forms Addresses CodeRabbit review on the Cloud SQL form, and applies the same fixes to the Spanner form which shared both issues (BigQueryForm already handled them correctly): - Reject whitespace-only service-account JSON on submit. The `required` attribute on a <textarea> does not trim, so " " passed the browser check and reached onSave with an effectively blank credential. Submit now treats a trim-empty value as missing and surfaces a dedicated "required" error. - Clear the validation error in the reset effect, so switching integrations or reloading a valid config no longer leaves a stale error that blocks Save. Adds the corresponding `...ServiceAccountRequired` localization strings + wiring. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019VuoSZXF8YHsN81Lra45JW
Add Cloud SQL to specs/INTEGRATIONS_CREDENTIALS.md (supported-types list, config interface example and the Google Cloud forms section) and bump the integration count 18 -> 19. Addresses the CodeRabbit "Updates Docs" check. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019VuoSZXF8YHsN81Lra45JW
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/webviews/webview-side/integrations/SpannerForm.tsx (1)
45-52: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winExtract the shared service-account validation path.
This reset + trim/required/JSON-validation flow now exists in both
SpannerFormandCloudSqlForm, so the next change will likely update one and miss the other. Please move it into a shared helper (or shared field component) and reuse it from both forms. As per coding guidelines, "Extract duplicate logic into helper methods to prevent drift following DRY principle".Also applies to: 95-110
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/webviews/webview-side/integrations/SpannerForm.tsx` around lines 45 - 52, The service-account reset, trim/required check, and JSON validation logic is duplicated in SpannerForm and CloudSqlForm, so extract it into a shared helper or reusable field component and call it from both forms. Move the common validation flow out of the SpannerForm effect/handler and the matching CloudSqlForm path, keeping the unique integration-specific state updates separate. Reuse the shared logic via the existing SpannerForm and CloudSqlForm service-account handling symbols so future changes only need one update.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@src/webviews/webview-side/integrations/SpannerForm.tsx`:
- Around line 45-52: The service-account reset, trim/required check, and JSON
validation logic is duplicated in SpannerForm and CloudSqlForm, so extract it
into a shared helper or reusable field component and call it from both forms.
Move the common validation flow out of the SpannerForm effect/handler and the
matching CloudSqlForm path, keeping the unique integration-specific state
updates separate. Reuse the shared logic via the existing SpannerForm and
CloudSqlForm service-account handling symbols so future changes only need one
update.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: f29da3d5-eba5-4e11-b085-4aa171e5aacb
📒 Files selected for processing (6)
specs/INTEGRATIONS_CREDENTIALS.mdsrc/messageTypes.tssrc/notebooks/deepnote/integrations/integrationWebview.tssrc/platform/common/utils/localize.tssrc/webviews/webview-side/integrations/CloudSqlForm.tsxsrc/webviews/webview-side/integrations/SpannerForm.tsx
🚧 Files skipped from review as they are similar to previous changes (4)
- src/notebooks/deepnote/integrations/integrationWebview.ts
- src/messageTypes.ts
- src/webviews/webview-side/integrations/CloudSqlForm.tsx
- src/platform/common/utils/localize.ts
The "required + valid-JSON" check for service-account credentials was duplicated across the Cloud SQL, Spanner and BigQuery forms. Extract it into a pure, dependency-free `validateServiceAccountJson()` helper and reuse it in all three forms (both the change and submit handlers). BigQuery keeps its detailed "Invalid JSON: <detail>" message via the helper's `detail` field, so behavior is unchanged everywhere. The helper has no React/localization dependencies, so it is unit-tested in isolation. Addresses finding #1 from the TypeScript code review. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019VuoSZXF8YHsN81Lra45JW
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/webviews/webview-side/integrations/serviceAccountValidation.ts`:
- Around line 23-29: The validation in serviceAccountValidation should not treat
every successful JSON.parse as valid; it currently returns null for values like
null, arrays, strings, and numbers. Update the logic in the helper used by
CloudSqlForm and BigQueryForm so that after JSON.parse(trimmed) succeeds, it
verifies the parsed value is a non-null plain object before returning success,
and otherwise returns an invalid-json-style result. Keep the existing invalid
JSON error handling, but add the non-object rejection in the same validation
path.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: ee6a4b46-5489-44dd-b588-66bbb8b368e4
📒 Files selected for processing (5)
src/webviews/webview-side/integrations/BigQueryForm.tsxsrc/webviews/webview-side/integrations/CloudSqlForm.tsxsrc/webviews/webview-side/integrations/SpannerForm.tsxsrc/webviews/webview-side/integrations/serviceAccountValidation.tssrc/webviews/webview-side/integrations/serviceAccountValidation.unit.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- src/webviews/webview-side/integrations/SpannerForm.tsx
- src/webviews/webview-side/integrations/CloudSqlForm.tsx
…ject `validateServiceAccountJson` only checked that `JSON.parse` succeeded, so `JSON.parse`-valid but non-object payloads (`123`, `"foo"`, `null`, `[]`) passed validation and could be saved as service accounts, failing only later. Reject anything that is not a non-null, non-array object. Covers the Cloud SQL, Spanner and BigQuery forms via the shared helper. Addresses CodeRabbit review feedback. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019VuoSZXF8YHsN81Lra45JW
Brings in #432 (Cloud SQL integration support). Resolved the package.json and package-lock.json conflicts by keeping this branch's newer @deepnote/* versions (blocks 4.6.0, convert 4.0.0, runtime-core 0.4.0); @deepnote/database-integrations is 1.5.0 on both sides, and the Cloud SQL source from #432 merged cleanly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P2CLu8UmD8ceGNyv8u96pQ
Summary
Bumps
@deepnote/database-integrationsfrom^1.4.3to^1.5.0, which adds the newcloud-sqldatabase integration type, and wirescloud-sqlthrough the extension following the convention used by the other integrations.Changes
Dependency
@deepnote/database-integrations1.4.3→1.5.0Required to keep
tscpassing (the exhaustiveRecord<ConfigurableDatabaseIntegrationType, …>maps that broke):integrationUtils.ts— addedcloud-sqltointegrationTypeLabels(Google Cloud SQL) andintegrationTypeIcons(+ logo import)sqlCellStatusBarProvider.ts— addedcloud-sqlto itsintegrationTypeLabelsFollowing the integration convention (closest model: Spanner, since
cloud-sqlmetadata is{ service_account: string }):icons/cloud-sql.svg— new GCP-style database iconCloudSqlForm.tsx— new form (name + Service Account JSON, matching the schema)ConfigurationForm.tsx— import +case 'cloud-sql'IntegrationItem.tsx—case 'cloud-sql'in the type-label switchIntegrationTypeSelector.tsx— Cloud SQL added to the Databases section, grouped with the other GCP databasesmessageTypes.ts, strings inlocalize.ts, wiring inintegrationWebview.tsOther touchpoints (
integrationDetector.ts,sqlLspConnectionUtils.ts, env-var/startup providers) already handle types generically via the package'sdatabaseIntegrationTypesor adefaultbranch, so no changes were needed there.Notes
In
1.5.0the package'sgetSqlAlchemyInputreturnsnullforcloud-sql(query execution isn't wired up in the package yet) and the metadata schema is justservice_account. The form therefore intentionally only collects the service-account JSON, faithful to the current schema. If the package later expands thecloud-sqlmetadata (e.g. instance/database), the form will need corresponding fields.Verification
tsc -p ./ --noEmit✅ (the 3 original errors are gone)compile-tsc✅,format-fix✅, ESLint on all changed files ✅🤖 Generated with Claude Code
https://claude.ai/code/session_019VuoSZXF8YHsN81Lra45JW
Summary by CodeRabbit