From fa41a17b0348c81f58c38037d65199970754b0aa Mon Sep 17 00:00:00 2001 From: CodeMash Date: Tue, 13 Oct 2026 19:41:05 +0300 Subject: [PATCH 1/2] build(deps): @norbix.ai/ts ^4.25.0 (marketplace OAuth sign-out route 30) Co-Authored-By: Claude Opus 5.5 --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9a210d2..7459f74 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "@commitlint/cli": "^21.2.2", "@commitlint/config-conventional": "^21.2.2", "@eslint/js": "^10.0.1", - "@norbix.ai/ts": "^4.24.0", + "@norbix.ai/ts": "^4.25.0", "@reduxjs/toolkit": "^2.12.0", "@semantic-release/commit-analyzer": "^13.0.1", "@semantic-release/github": "^12.0.9", @@ -1490,9 +1490,9 @@ } }, "node_modules/@norbix.ai/ts": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@norbix.ai/ts/-/ts-4.24.0.tgz", - "integrity": "sha512-YJrbsb/qvtVkjkzT+DZKVE0MhqxTbVD7K+tkNyB/Eh82dMEnJNu4kvM6YP/t9tbYms5N4rilcl9zISr/VTTDUQ==", + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@norbix.ai/ts/-/ts-4.25.0.tgz", + "integrity": "sha512-izKpx/INFqGyoluT44C7M3lE+29Qelkd40OT6YBHi4TkYcWXSt5P4BUx9B+8j2dm3bAmyL2fw6p5R7zvNaxIsQ==", "dev": true, "license": "MIT", "engines": { diff --git a/package.json b/package.json index c81db94..2a1f28a 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "@commitlint/cli": "^21.2.2", "@commitlint/config-conventional": "^21.2.2", "@eslint/js": "^10.0.1", - "@norbix.ai/ts": "^4.24.0", + "@norbix.ai/ts": "^4.25.0", "@reduxjs/toolkit": "^2.12.0", "@semantic-release/commit-analyzer": "^13.0.1", "@semantic-release/github": "^12.0.9", From e694cba8d8257b87d95d489b2abc92f28a95fc86 Mon Sep 17 00:00:00 2001 From: CodeMash Date: Tue, 13 Oct 2026 19:41:55 +0300 Subject: [PATCH 2/2] feat(marketplace): useSignOutMarketplaceIntegrationMutation, the OAuth sign-out (route 30) The hook invalidates that connection's tag (signedIn changes) and its ACCESS tag, and nothing of another connection. Wire case through the real SDK (POST .../oauth/sign-out, no body), tag test, README row. Co-Authored-By: Claude Opus 5.5 --- README.md | 1 + src/hooks/hub/marketplace.ts | 7 +++++++ tests/marketplace.test.ts | 19 ++++++++++++++++++- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 800911d..240bda9 100644 --- a/README.md +++ b/README.md @@ -558,6 +558,7 @@ added on a connection (`func_…`). Every tag is of type `CodeMarketplace`. | Connections | `useGetMarketplaceIntegrationsQuery`, `useGetMarketplaceIntegrationQuery`, `useSaveMarketplaceIntegrationMutation`, `useDeleteMarketplaceIntegrationMutation`, `useEnableMarketplaceIntegrationMutation`, `useDisableMarketplaceIntegrationMutation`, `useReplaceMarketplaceIntegrationSecretsMutation`, `useRevealMarketplaceIntegrationSecretsMutation`, `useSetMarketplaceIntegrationTokenMappingsMutation`, `useTestMarketplaceIntegrationMutation`, `useGetMarketplaceFunctionCatalogQuery`, `useGetMarketplaceIntegrationToolsQuery` (the stored MCP tool catalog of an MCP connection, core SDK 4.23.0+) | `INTEGRATIONS`, ``, `CATALOG:`, `TOOLS:` (test and delete invalidate it); reveal touches nothing | | Access | `useGetMarketplaceIntegrationAccessQuery` (the access matrix of a connection: roles, packages, tools, functions), `useSetMarketplaceIntegrationRoleAccessMutation` (a role's package + Manage), `useSaveMarketplaceIntegrationCustomAccessMutation` (a custom policy for one role) — core SDK 4.24.0+ | `ACCESS:`; the two writes invalidate only that connection's matrix, and so do test, delete, function save and function delete | | Sign-in | `useStartMarketplaceIntegrationSignInMutation` (OAuth sign-in of an MCP connection: open `authorizeUrl`; core SDK 4.24.0+) | invalidates nothing — read the connection again (`signedIn`) after the person returns | +| Sign-out | `useSignOutMarketplaceIntegrationMutation` (OAuth sign-out of an MCP connection: `wasSignedIn`, `revoke`; core SDK 4.25.0+) | invalidates `` and `ACCESS:` of that connection | | Functions | `useGetMarketplaceFunctionsQuery`, `useGetMarketplaceFunctionQuery`, `useSaveMarketplaceFunctionMutation`, `useDeleteMarketplaceFunctionMutation`, `useEnableMarketplaceFunctionMutation`, `useDisableMarketplaceFunctionMutation`, `useGetMarketplaceFunctionTokensQuery`, `useInvokeMarketplaceFunctionMutation`, `useGetMarketplaceFunctionRunsQuery` | `FUNCTIONS:`, ``, `RUNS`; invoke touches nothing | Revealing secrets is a mutation on purpose: a query would keep the clear values diff --git a/src/hooks/hub/marketplace.ts b/src/hooks/hub/marketplace.ts index 9a90cf0..f39db40 100644 --- a/src/hooks/hub/marketplace.ts +++ b/src/hooks/hub/marketplace.ts @@ -56,6 +56,7 @@ export const hubCodeMarketplace = (b: Builder) => { type SetRoleAccess = Fn<'setMarketplaceIntegrationRoleAccess'>; type SaveCustomAccess = Fn<'saveMarketplaceIntegrationCustomAccess'>; type StartSignIn = Fn<'startMarketplaceIntegrationSignIn'>; + type SignOut = Fn<'signOutMarketplaceIntegration'>; type GetFunctions = Fn<'getMarketplaceFunctions'>; type GetFunction = Fn<'getMarketplaceFunction'>; type SaveFunction = Fn<'saveMarketplaceFunction'>; @@ -188,6 +189,12 @@ export const hubCodeMarketplace = (b: Builder) => { startMarketplaceIntegrationSignIn: b.mutation, Arg>({ query: (args) => (norbix) => callHC(norbix).startMarketplaceIntegrationSignIn(args), }), + // Sign-out (route 30, core SDK 4.25.0) changes the connection at once (`signedIn` false) + // and its access (the connection's MCP tools are no longer reachable). + signOutMarketplaceIntegration: b.mutation, Arg>({ + query: (args) => (norbix) => callHC(norbix).signOutMarketplaceIntegration(args), + invalidatesTags: (_res, _err, arg) => [{ type: T, id: integrationId(arg) }, access(arg)], + }), // ---- Functions on a connection ---- getMarketplaceFunctions: b.query, Arg>({ diff --git a/tests/marketplace.test.ts b/tests/marketplace.test.ts index 053a32d..4af6cf0 100644 --- a/tests/marketplace.test.ts +++ b/tests/marketplace.test.ts @@ -133,6 +133,7 @@ const CASES: Array< }, ], ['startMarketplaceIntegrationSignIn', 'mutation', 'POST', `${I}/oauth/start`, IDS, {}], + ['signOutMarketplaceIntegration', 'mutation', 'POST', `${I}/oauth/sign-out`, IDS, {}], ['getMarketplaceFunctions', 'query', 'GET', `${I}/functions`, IDS, {}], ['getMarketplaceFunction', 'query', 'GET', `${I}/functions/${FUNCTION}`, FN_IDS, {}], [ @@ -187,7 +188,7 @@ function tagsFor(tags: Tags | undefined, arg: unknown): unknown { const endpoints = hubCodeMarketplace(fakeBuilder()) as unknown as Record; describe('hubCodeMarketplace', () => { - it('wraps the 28 marketplace methods of the published core SDK', () => { + it('wraps the 29 marketplace methods of the published core SDK', () => { expect(Object.keys(endpoints).sort()).toEqual([...NAMES].sort()); }); @@ -292,6 +293,22 @@ describe('hubCodeMarketplace', () => { expect(endpoints['startMarketplaceIntegrationSignIn']!.invalidatesTags).toBeUndefined(); }); + it('signing out invalidates the connection and its ACCESS tag, only for that connection (core SDK 4.25.0)', () => { + expect(endpoints['signOutMarketplaceIntegration']!.__kind).toBe('mutation'); + expect(tagsFor(endpoints['signOutMarketplaceIntegration']!.invalidatesTags, IDS)).toEqual([ + { type: 'CodeMarketplace', id: INTEGRATION }, + { type: 'CodeMarketplace', id: `ACCESS:${INTEGRATION}` }, + ]); + expect( + tagsFor(endpoints['signOutMarketplaceIntegration']!.invalidatesTags, { + integrationViewId: 'int_other', + }), + ).toEqual([ + { type: 'CodeMarketplace', id: 'int_other' }, + { type: 'CodeMarketplace', id: 'ACCESS:int_other' }, + ]); + }); + it('the last runs provide CodeMarketplace/RUNS', () => { expect(tagsFor(endpoints['getMarketplaceFunctionRuns']!.providesTags, {})).toEqual([ { type: 'CodeMarketplace', id: 'RUNS' },