Repository navigation
fix(service-datasource): an adopted plugin driver's failed-credentials verdict clears on the next granted borrow, and the connector path withholds the form-encoded credential spelling - #27990
Conversation
…edentials verdict on the next granted borrow The connector credential source announces each granted borrow (onLent), the datasource connection service retracts the already-registered guard's verdict for that instance, and the connector call path takes its withheld spellings from borrowedCredentialForms. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ihL2eVFL4vpCbzypgy7JU
…tor call path Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ihL2eVFL4vpCbzypgy7JU
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ihL2eVFL4vpCbzypgy7JU
…ble's map Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ihL2eVFL4vpCbzypgy7JU
📓 Docs Drift CheckThis PR changes 3 package(s): ⛔ 1 release-owned page(s) name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 16 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 0ffea305ede5a118e43037eff9569ec632908cff && git checkout 0ffea305ede5a118e43037eff9569ec632908cff
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin b6db3692e2f3103c2a06d3cb53320d706dc42ddc 016e23cd5c389a8642ef5f514b7c90aa8b558620 && git checkout -B drift-repro b6db3692e2f3103c2a06d3cb53320d706dc42ddc && git merge --no-ff 016e23cd5c389a8642ef5f514b7c90aa8b558620
node scripts/docs-audit/affected-docs.mjs --json b6db3692e2f3103c2a06d3cb53320d706dc42ddc
|
|
epic:#27261#1 · marchtian · session_017ihL2c5z3q4h8inrn5kwqV Contract reviewServed-tier: ① Derived judgments
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS |
|
epic:#27261#1 · marchtian · session_017ihL2c5z3q4h8inrn5kwqV 维护者速读
席位意见:ACCEPT。契约复核 PASS 在案(6516578586, 席位核对
|
Requested by 田騏 · project thread
Fable review owed.
Clause-②: yes (widening)(a new optional member on a published@objectstack/typescontract), so it lands after a contract review PASS on the current head.Fixes #27919
Clause-②: yes (widening)
Metadata-protocol: none
维护者速读
auth)被判failed-credentials,现在实例修好后,下一次出借该实例凭据成功时,这个判定和引擎的不可用标记就自动撤销,不用重启。出借方(自动化服务)新增可选的onLent(listener),每次成功出借都按实例名通知;数据源连接服务订阅它。另外,连接器自身调用路径的credentialForms改为直接用borrowedCredentialForms,补上了表单编码(空格写成+)这种写法的脱敏。onLent,行为与现在相同,降级启动横幅仍写「需重启」。回滚即 revert。packages/services/service-datasource/src/datasource-connection-service.ts的已注册守卫、subscribeToLends、retractOnLend;packages/types/src/connector-credential-source.ts的onLent;packages/services/service-automation/src/connector-credentials.ts的credentialForms。pnpm --filter @objectstack/service-datasource exec vitest run src/__tests__/datasource-connector-credential.test.ts,预期 24 个用例全绿,其中新的 5 个在 "clears on the next granted borrow" 下。What changes
The contract (
packages/types/src/connector-credential-source.ts):IConnectorCredentialSourcegains an optionalonLent(listener). The listener is called with the connector instance's name each timeborrowgrants a handle, whoever asked (a driver's request, a connect, a probe); it returns the unsubscribe; a listener's throw never fails the borrow. A borrow judges the declaration, so a grant proves the instance can lend now. The docblock ofborrowedCredentialFormsnow says the connector call path takes its list from it.The lender (
packages/services/service-automation/src/connector-credential-source.ts): implementsonLent. A granted borrow is announced after the declaration check passes and before the handle is built; a refusal is never announced; each listener is called in its own try/catch.The borrower (
packages/services/service-datasource/src/datasource-connection-service.ts): when the already-registered guard (the one connect an adopted plugin driver reaches) recordsfailed-credentials, the service subscribes to the lender'sonLent(once per lender) and keeps the datasource's name with the instance it names and the reason recorded. On a grant for THAT instance,retractOnLendre-records the datasourcealready-registered, which clears the engine's unavailable mark, but only while the retained state is still that verdict and the plugin's driver is still registered. A grant for any other instance leaves it standing. A connect, reconnect or disconnect of the datasource drops the entry (it records its own verdict), anddisconnectAllreleases the subscriptions. With no lender, or a lender withoutonLent, nothing changes: the verdict stays until a restart.handleFailuretakes an optionalrecoverysentence for the degraded-boot banner, so the guard's banner says the first granted borrow clears it; every other caller keeps the "reachable AND the server is restarted" text.The connector call path (
packages/services/service-automation/src/connector-credentials.ts):credentialForms(value, username?)keeps its signature and its three callers, and now delegates toborrowedCredentialForms(abasicauth when a username is given, else a bearer one). Its local base64 helper is gone. The list gains the form encodingURLSearchParamswrites.Changeset:
patchon@objectstack/types,@objectstack/service-automationand@objectstack/service-datasource(Metadata-protocol: nonetakes patch).Why
The two non-blocking should-fixes of the delta contract review of #27819 (record 6514494060, VERDICT PASS on
3351ae35), filed as this card under epic #27261. The card preferred clearing the verdict on the next successful borrow over rewording the banner; this does that, and the banner states which recovery applies.Verification
On the branch head
016e23cd(origin/main9900366emerged in; its incoming commits touch none of these files, and theservice-automationsuite was rerun after the merge: 219 files, 2824 passed):service-datasourcedatasource-connector-credential.test.ts(5): on a realObjectQLengine and the realDatasourceAdminServicePlugin, a disabled instance recordsfailed-credentialswith the engine's mark; a grant for another instance (salesforce_crm) leaves both; after the repair, a grant forsap_s4re-recordsalready-registered, availabilityavailable, no reason, no mark, driver still registered. One subscription per lender for two waiting datasources, released bydisconnectAll. A disconnect before the grant resurrects nothing. A driver evicted before the grant keeps the verdict. The degraded-boot banner names the next granted borrow with a lender that hasonLent, and keeps the restart sentence with one that lacks it.service-automationconnector-credential-source.test.ts(2):onLentnames the instance on a grant, never on a refusal (disabled, undeclared), and stops after the unsubscribe; a throwing listener does not fail the borrow and later listeners still run.connector-credential-door.test.ts(1): an api-key instance whose upstream 401 body echoes the form-encoded query string; no form-encoded, percent-encoded or raw spelling reaches the degraded reason, the credential listing or the logs.git status --porcelainempty after each):retractOnLendmade a no-op: the retraction case fails; the connector-name match removed: the same case fails (the other-instance grant clears it); the form-encoded spelling filtered out ofcredentialForms: the new door case fails.@objectstack/types,@objectstack/service-automation(withcheck:test-typecheck),@objectstack/service-datasource: exit 0. Lint: eslint on the changed files, clean.@objectstack/types33 files, 832 passed;@objectstack/service-datasource65 files, 1069 passed;@objectstack/service-automation219 files, 2821 passed;@objectstack/driver-odata(the borrowing presenter, unchanged) 7 files, 727 passed.dispatch-gates --commandsderived 62 families on the merged head; all run with exit codes recorded before any pipe;--ran: 62 derived, 62 run, 0 NOT-MEASURED (a DERIVED zero). On the first passcheck-plugin-teardown-shape --self-testandcheck:dual-build-cjs-loadsexited 3 (fixture commit not fetched, packages not built) and passed once those prerequisites were met.Acceptance notes
credentialFormsis kept as the connector path's adapter, not removed. Its callers hold a value and an optional basic username, not aBorrowedConnectorAuth, and one of them (the credential door's write) has noauthat all. The adapter is two lines overborrowedCredentialForms, so there is one list of spellings.Human Minimum
packages/specholds no runtime logic. (Not touched.)main, one pull request.packages/spectouched: not touched.content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.Generated by Claude Code
🤖 Generated with Claude Code
https://claude.ai/code/session_017ihL2eVFL4vpCbzypgy7JU