release: v1.2 Connector SDK & Plugin Seam → dev - #1142
Conversation
…ach-in (#1123) - Delete unused generalized/errors.ts (ConnectionError/QueryError/SchemaError/ QueryTimeoutError) + its test + index re-export; the live error system is ConnectorError, which nothing replaced these with. - Fix extractNodeAndRelPropertiesFromRecords to read the public neo4j-driver Record API (keys/get) instead of the private _fields array (breaks silently on driver upgrades). New neo4j/__tests__/utils.test.ts covers node/rel/path. - Remove empty BaseAdvancedOptions interface + export. checkConnection is already unified (#900) and ConnectionTypes is load-bearing via query-executor + audit (moved to #1121), so neither is touched here. Closes #1116 Closes #996 Co-authored-by: alfredorubin96 <alfredo.rubin@neotechnology.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* feat(connection): extract @neoboard/connector-sdk and dogfood it New publishable (0.1.0, unpublished) workspace package @neoboard/connector-sdk holding the stable connector contract, extracted out of @neoboard/connection: plugin interface + registry factory, ConnectionModule/AuthenticationModule base classes, ConnectorError + detection, core config/result types, NeodashRecord(+ parser), query-safety helpers (collectUpToLimit), schema data types, and the connector-type constants. - connection/ now depends on the SDK and re-exports it, so the @neoboard/connection public API (incl. the /connector-types subpath, via a thin shim) is unchanged. - Neo4j + PostgreSQL connectors refactored onto the SDK — no parallel type copy, no behavior change. - Build order: SDK builds before connection (its dist provides the types); generate-connector-imports codegen now emits the SDK import path. - Tests: 6 contract tests split by ownership — 3 pure-SDK tests moved into the SDK package (Docker-free jest); the 3 that exercise concrete modules/registry stay in connection. jest maps the SDK to source; globalSetup imports SDK source directly. Schema *types* only — the SchemaManager interface is deferred to #1119. ConnectionTypes enum moved as-is (collapse deferred to #1121). Part of #1093. Refs #1117 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: update lockfile for @neoboard/connector-sdk workspace Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ci(connector-sdk): build SDK before connection in CI + Docker (#1117) The connector-sdk workspace extraction added @neoboard/connector-sdk as a dependency connection resolves via its built dist, but only the root build script was updated to compile it first. The CI typecheck / unit-tests / e2e jobs and the Dockerfile hand-roll `npm -w connection run build` without a preceding SDK build, so connection's tsc fails with TS2307 (cannot find @neoboard/connector-sdk) on a clean checkout. - ci.yml: build connector-sdk before connection in all three jobs. - Dockerfile: COPY connector-sdk/package.json (npm ci needs the workspace manifest) and build the SDK before connection. - eslint.config.js: ignore connector-sdk at the root like its sibling connection (both have their own setups); restores the pre-extraction state where this code was not root-linted. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(connector-sdk): add README + LICENSE for publish hygiene (#1117) package.json `files` referenced README.md and LICENSE that didn't exist — `npm publish` would have shipped the package without them. Add a concise README (contract overview + quick start) and copy the repo's ELv2 LICENSE. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: alfredorubin96 <alfredo.rubin@neotechnology.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
… (#1132) * test(component): failing spec for DynamicConnectionFields (#1118 WIP, TDD red) Parking #1118 at a clean red checkpoint to pivot to the design-system audit (Epic A). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(connector): dynamic connection form from plugin.formFields (#1118) Render the connection form from a connector's formFields instead of hardcoded per-connector input arrays. - component: new DynamicConnectionFields — controlled renderer for text/number/password/select/boolean fields, required markers, descriptions, per-field errors. Default `conn-` id prefix preserves existing E2E selectors. (turns the parked TDD-red spec green) - connection: built-in field defs single-sourced in client-safe form-fields.ts (no driver imports) and exposed via the new @neoboard/connection/form-fields subpath; neo4j/pg plugins reference them. - app: connections create dialog credential block is now generated from plugin.formFields via connectionFieldsFor(). Verified: component 11/11, connection unit 23/23, app tsc + lint clean, connections E2E 15/15. Closes #1118 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: alfredorubin96 <alfredo.rubin@neotechnology.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
) (#1136) * feat(connection): schema-manager registry keyed by connector type (#1119) Schema introspection dispatched on a hardcoded 'neo4j' | 'postgresql' branch in app/schema-prefetch — a registry-supplied connector couldn't provide its own schema manager. - sdk: host the SchemaManager contract in @neoboard/connector-sdk and add an optional createSchemaManager() factory to ConnectorPlugin (mirrors createModule). Optional → connectors without introspection resolve to undefined. - connection: built-in Neo4j + Postgres plugins declare createSchemaManager(); schema/schema-manager re-exports the SDK contract (stable import path); new getSchemaManager(type) registry helper. - app: schema-prefetch resolves via getSchemaManager(type) — the hardcoded if/else is gone; an unknown/introspection-less type yields null (schema is a non-critical cache). Registry-refactor only; #569's introspection counts + visualization shape are deferred (stays open). Closes #1119 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(connector): cover fetchConnectionSchema registry dispatch (#1119) SonarCloud new-code coverage gate failed (54.5% < 80%): the rewritten fetchConnectionSchema branches were E2E-only. Route getSchemaManager through connection-adapter (the app's mockable connection seam) and add unit tests for both branches (manager resolved → fetch; none → null) plus prefetchSchema's fire-and-forget + error-swallow paths. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * refactor(connector-sdk): open DatabaseSchema.type for registry plugins (#1119) Addresses CodeRabbit (Major): now that getSchemaManager resolves arbitrary connector types, a registry-supplied plugin's createSchemaManager() could not describe its own type — DatabaseSchema.type was pinned to 'neo4j' | 'postgresql'. Widen to an open string so external connectors express their type through the SchemaManager contract without editing core SDK types. Built-ins still use "neo4j" / "postgresql". Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: alfredorubin96 <alfredo.rubin@neotechnology.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…age (#1120) (#1137) * feat(component): route query-editor language from plugin.queryLanguage (#1120) The editor picked its CodeMirror language from the connector *type* and fell back to SQL for anything unregistered — a registry-supplied connector got the wrong language (or misleading SQL highlighting). - component: resolveLanguageExt falls back to plain text (no extensions, no highlighting) for unregistered languages instead of SQL. - connection: new client-safe query-languages.ts (CONNECTOR_QUERY_LANGUAGES, no driver imports) → @neoboard/connection/query-languages subpath; built-in plugins source their queryLanguage from it. - app: widget-editor-modal derives editorLanguage from CONNECTOR_QUERY_LANGUAGES (the connector's queryLanguage) instead of its type; unknown/no connector → plain text. This also fixes the latent `=== "sql"` placeholder check that was always false when given the connector type. Deferred to #1121: the separate hardcoded CONNECTOR_LANGUAGES display map. Verified: resolver 16/16, connection 23/23, app tsc + lint clean, code-completion E2E 6/6. Closes #1120 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(connector): cover editor-language routing via extracted helper (#1120) SonarCloud new-code coverage gate failed (58.3% < 80%): the editorLanguage derivation lived inline in the untested widget-editor-modal. Extract it to a pure editorLanguageForConnector() helper and unit-test all branches (neo4j→cypher, postgresql→sql, unknown/none→plain text); the modal now calls the helper. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: alfredorubin96 <alfredo.rubin@neotechnology.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…tor/storage (#1121) (#1138) * feat(app): de-hardcode connector type unions through validation/executor/storage (#1121) Several paths assumed only the built-in 'neo4j' | 'postgresql' union, so a registry-supplied connector type couldn't flow through the app. - validation: schemas.ts accepts any registry-registered type via a runtime refine (isRegisteredConnectorType, routed through connection-adapter for test mockability) instead of z.enum(CONNECTOR_TYPES). - execution: query-executor DbType widened to string; toConnectionTypeEnum maps unknown types to a new ConnectionTypes.UNKNOWN sentinel rather than mislabeling them PostgreSQL. pipeline-types.connectionType + prefetchSchema widened to string. - storage: connection.type column pgEnum -> text; the accepted set is enforced at the API layer, not the DB. Migrations squashed 12 -> 1 (pre-launch, no users): the single initial now creates connection.type as text from the start, so there's no connection_type enum at all. CLI built-in list left as-is on purpose: a registry/external connector already lists via neoboard-connectors.json, and coupling the *published* @neoboard/cli to the *unpublished* @neoboard/connector-sdk would break `npm i -g`. Adding a built-in is itself a core change, so the "no core change per registry type" acceptance still holds. Verified: app tsc + lint clean, connections E2E 15/15 (squashed migration applies + registry validation + text-column store). Closes #1121 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(connector): stub registry validation in connection route tests (#1121) Registry-driven connector-type validation made schemas.ts transitively import the driver-heavy connection registry via connection-adapter. Route tests that validate `type` (create / test-inline / list-databases-inline) don't mock that seam, so `getConnector` was undefined under Vitest (production/E2E load it fine). Stub isRegisteredConnectorType in those three tests (true for built-ins, false otherwise — preserves the mysql→400 cases), and add a dedicated registered-types unit test for coverage. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: alfredorubin96 <alfredo.rubin@neotechnology.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…1139) A reusable, framework-agnostic harness shipped from @neoboard/connector-sdk that any connector runs to prove it honors Query Safety. buildConformanceCases returns {name, run}[] whose run() throws on violation, so connectors wire the cases into their own test runner without the SDK depending on one. Checks: - read-only: a write query is rejected under READ access mode - MAX_ROWS+1: results capped at rowLimit, truncation flagged (COMPLETE_TRUNCATED) - timeout: a slow query times out / fails within the configured timeout The contract has no generic cancel API, so cancellation-cleanup ("no leaked cursor after a timed-out query") is exposed as an optional connector-supplied assertNoLeak() hook rather than a generic check (the built-ins' cursor cleanup is already guarded by the #978 pg-cursor timeout tests). Wires both built-ins (Neo4j + PostgreSQL) via Testcontainers integration tests. Closes #1122 Co-authored-by: alfredorubin96 <alfredo.rubin@neotechnology.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…GUAGES (#1140) The hardcoded CONNECTOR_LANGUAGES map ({neo4j:"Cypher", postgresql:"SQL"}) duplicated plugin.queryLanguage — already single-sourced client-safe as CONNECTOR_QUERY_LANGUAGES (#1120). Its only two consumers (widget-library + template-browser CodePreview) used it purely as a language key (CodePreview lowercases it), so: - both now read CONNECTOR_QUERY_LANGUAGES; unknown connector type → "" (plain text) instead of defaulting to Cypher - CONNECTOR_LANGUAGES removed from the SDK definition and the whole re-export chain (connector-sdk → connection → app) Deferred follow-up from the v1.2 connector epic (#1093). Functionally identical for built-ins. Co-authored-by: alfredorubin96 <alfredo.rubin@neotechnology.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…rtNoLeak hook (#1141) Ponytail trim of the v1.2 connector epic before consolidating release/1.2 → dev: - registered-types: remove registeredConnectorTypes() — zero callers (only isRegisteredConnectorType is used, by schemas.ts). Drop its getAllConnectors plumbing from connection-adapter + the test block. - conformance harness: remove the assertNoLeak hook — no connector wired it, so it was an unused extension point. The suite covers the 3 generically-verifiable safety checks; cancellation-cleanup for the built-ins is guarded by the #978 pg-cursor timeout tests. Verified: sdk + connection build, app tsc + lint clean. Co-authored-by: alfredorubin96 <alfredo.rubin@neotechnology.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 47 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (133)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|



Consolidates the v1.2 Connector SDK & Plugin Seam epic (#1093) from
release/1.2intodev.devhas not advanced since the branch point, so this is a conflict-free merge.Included (10 PRs)
Epic (#1116–#1122):
@neoboard/connector-sdkplugin.formFieldsplugin.queryLanguageFollow-ups:
CONNECTOR_LANGUAGESmapregisteredConnectorTypes+ unusedassertNoLeakhook)Net effect
The connector layer is now a versioned SDK + runtime plugin registry: external connectors are first-class through the form, schema, query-language, validation, execution, and storage layers, with a shared query-safety conformance harness. Every constituent PR landed 100% green (CI + SonarCloud + CodeRabbit).
Note: DB migrations were squashed 12→1 (pre-launch, no users) —
connection.typeis nowtext, noconnection_typeenum.🤖 Generated with Claude Code