@shipfox/client-onboarding 22.0.2 → 22.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-setup-route.d.ts","sourceRoot":"","sources":["../src/workspace-setup-route.ts"],"names":[],"mappings":"AASA,OAAO,EAGL,KAAK,0BAA0B,EAC/B,KAAK,mBAAmB,EACzB,MAAM,+BAA+B,CAAC;AAMvC,YAAY,EAAC,0BAA0B,EAAC,MAAM,+BAA+B,CAAC;AAE9E,wBAAsB,uBAAuB,CAAC,EAC5C,WAAW,EACX,WAAW,EACX,aAAa,EACb,QAAQ,GACT,EAAE,0BAA0B,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAsE3D"}
1
+ {"version":3,"file":"workspace-setup-route.d.ts","sourceRoot":"","sources":["../src/workspace-setup-route.ts"],"names":[],"mappings":"AAUA,OAAO,EAGL,KAAK,0BAA0B,EAC/B,KAAK,mBAAmB,EACzB,MAAM,+BAA+B,CAAC;AAMvC,YAAY,EAAC,0BAA0B,EAAC,MAAM,+BAA+B,CAAC;AAE9E,wBAAsB,uBAAuB,CAAC,EAC5C,WAAW,EACX,WAAW,EACX,aAAa,EACb,QAAQ,GACT,EAAE,0BAA0B,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAsE3D"}
@@ -1,4 +1,4 @@
1
- import { isModelProviderOnboardingDismissed, modelProviderConfigsQueryOptions } from '@shipfox/client-agent';
1
+ import { isModelProviderOnboardingDismissed, modelProviderCatalogQueryOptions, modelProviderConfigsQueryOptions } from '@shipfox/client-agent';
2
2
  import { sourceConnectionsQueryOptions } from '@shipfox/client-integrations';
3
3
  import { projectExistenceQueryOptions } from '@shipfox/client-projects';
4
4
  import { userWorkspacesQueryOptions, WorkspaceSetupLoadError } from '@shipfox/client-shell/runtime';
@@ -118,14 +118,21 @@ async function fetchWorkspaceSourceConnections(queryClient, workspaceId) {
118
118
  }
119
119
  async function hasHandledModelProviderOnboarding(queryClient, workspaceId) {
120
120
  if (isModelProviderOnboardingDismissed(workspaceId)) return true;
121
- const options = modelProviderConfigsQueryOptions(workspaceId);
122
- try {
123
- const configs = await queryClient.fetchQuery(options);
121
+ const catalogOptions = modelProviderCatalogQueryOptions();
122
+ const configOptions = modelProviderConfigsQueryOptions(workspaceId);
123
+ const [catalogResult, configsResult] = await Promise.allSettled([
124
+ queryClient.fetchQuery(catalogOptions),
125
+ queryClient.fetchQuery(configOptions)
126
+ ]);
127
+ if (catalogResult.status === 'fulfilled' && catalogResult.value.workspaceProviders === 'disabled') {
128
+ return true;
129
+ }
130
+ if (configsResult.status === 'fulfilled') {
131
+ const configs = configsResult.value;
124
132
  return configs.configs.length > 0;
125
- } catch {
126
- const cached = queryClient.getQueryData(options.queryKey);
127
- return cached?.configs.length !== 0;
128
133
  }
134
+ const cached = queryClient.getQueryData(configOptions.queryKey);
135
+ return cached?.configs.length !== 0;
129
136
  }
130
137
  function normalizePath(pathname) {
131
138
  if (pathname === '/') return pathname;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/workspace-setup-route.ts"],"sourcesContent":["import {\n isModelProviderOnboardingDismissed,\n modelProviderConfigsQueryOptions,\n} from '@shipfox/client-agent';\nimport {\n type IntegrationConnection,\n sourceConnectionsQueryOptions,\n} from '@shipfox/client-integrations';\nimport {projectExistenceQueryOptions} from '@shipfox/client-projects';\nimport {\n userWorkspacesQueryOptions,\n WorkspaceSetupLoadError,\n type WorkspaceSetupRouteOptions,\n type WorkspaceSetupState,\n} from '@shipfox/client-shell/runtime';\nimport type {QueryClient} from '@tanstack/react-query';\nimport {redirect} from '@tanstack/react-router';\n\nconst TRAILING_SLASHES_RE = /\\/+$/u;\n\nexport type {WorkspaceSetupRouteOptions} from '@shipfox/client-shell/runtime';\n\nexport async function loadWorkspaceSetupRoute({\n queryClient,\n workspaceId,\n workspaceSlug,\n pathname,\n}: WorkspaceSetupRouteOptions): Promise<WorkspaceSetupState> {\n const workspace = await fetchWorkspaceSummary(queryClient, workspaceId);\n const workspaceStatus = workspace?.status;\n switch (workspaceStatus) {\n case undefined:\n case 'active':\n break;\n case 'suspended':\n case 'deleted':\n return {hideProjectNavigation: true, unavailable: true};\n default:\n return assertNever(workspaceStatus);\n }\n\n const projects = await fetchWorkspaceProjectExistence(queryClient, workspaceId);\n const normalizedPathname = normalizePath(pathname);\n\n if (projects.projects.length > 0) {\n if (isIntegrationsIndexPath(normalizedPathname, workspaceSlug)) {\n throw redirect({\n to: '/w/$workspaceSlug/settings/integrations',\n params: {workspaceSlug},\n replace: true,\n });\n }\n\n return {hideProjectNavigation: false};\n }\n\n const sourceConnections = await fetchWorkspaceSourceConnections(queryClient, workspaceId);\n const hasSourceConnection = sourceConnections.length > 0;\n\n if (!hasSourceConnection) {\n if (isIntegrationSetupPath(normalizedPathname, workspaceSlug)) {\n return {hideProjectNavigation: true};\n }\n\n throw redirect({\n to: '/w/$workspaceSlug/integrations',\n params: {workspaceSlug},\n replace: true,\n });\n }\n\n if (isAgentSettingsPath(normalizedPathname, workspaceSlug)) {\n return {hideProjectNavigation: true};\n }\n\n const providerHandled = await hasHandledModelProviderOnboarding(queryClient, workspaceId);\n if (!providerHandled) {\n if (isModelProviderOnboardingPath(normalizedPathname, workspaceSlug)) {\n return {hideProjectNavigation: true};\n }\n\n throw redirect({\n to: '/w/$workspaceSlug/model-provider',\n params: {workspaceSlug},\n replace: true,\n });\n }\n\n if (isProjectCreationPath(normalizedPathname, workspaceSlug)) {\n return {hideProjectNavigation: true};\n }\n\n throw redirect({\n to: '/w/$workspaceSlug/projects/new',\n params: {workspaceSlug},\n replace: true,\n });\n}\n\nfunction assertNever(value: never): never {\n throw new Error(`Unhandled workspace status: ${JSON.stringify(value)}`);\n}\n\nasync function fetchWorkspaceSummary(queryClient: QueryClient, workspaceId: string) {\n try {\n const result = await queryClient.fetchQuery(userWorkspacesQueryOptions());\n return result.memberships.find((workspace) => workspace.id === workspaceId);\n } catch (error) {\n throw new WorkspaceSetupLoadError(error);\n }\n}\n\nasync function fetchWorkspaceProjectExistence(queryClient: QueryClient, workspaceId: string) {\n const options = projectExistenceQueryOptions(workspaceId);\n\n try {\n return await queryClient.fetchQuery(options);\n } catch (error) {\n const cached = queryClient.getQueryData<{projects: unknown[]}>(options.queryKey);\n if (cached !== undefined) return cached;\n throw new WorkspaceSetupLoadError(error);\n }\n}\n\nasync function fetchWorkspaceSourceConnections(queryClient: QueryClient, workspaceId: string) {\n const options = sourceConnectionsQueryOptions(workspaceId);\n\n try {\n return await queryClient.fetchQuery(options);\n } catch (error) {\n const cached = queryClient.getQueryData<IntegrationConnection[]>(options.queryKey);\n if (cached !== undefined) return cached;\n throw new WorkspaceSetupLoadError(error);\n }\n}\n\nasync function hasHandledModelProviderOnboarding(\n queryClient: QueryClient,\n workspaceId: string,\n): Promise<boolean> {\n if (isModelProviderOnboardingDismissed(workspaceId)) return true;\n\n const options = modelProviderConfigsQueryOptions(workspaceId);\n try {\n const configs = await queryClient.fetchQuery(options);\n return configs.configs.length > 0;\n } catch {\n const cached = queryClient.getQueryData<{configs: unknown[]}>(options.queryKey);\n return cached?.configs.length !== 0;\n }\n}\n\nfunction normalizePath(pathname: string) {\n if (pathname === '/') return pathname;\n return pathname.replace(TRAILING_SLASHES_RE, '');\n}\n\nfunction workspacePath(workspaceSlug: string, suffix: string) {\n return `/w/${workspaceSlug}${suffix}`;\n}\n\nfunction isIntegrationsIndexPath(pathname: string, workspaceSlug: string) {\n return pathname === workspacePath(workspaceSlug, '/integrations');\n}\n\nfunction isIntegrationSetupPath(pathname: string, workspaceSlug: string) {\n const basePath = workspacePath(workspaceSlug, '/integrations');\n return (\n pathname === basePath ||\n pathname.startsWith(`${basePath}/`) ||\n pathname === workspacePath(workspaceSlug, '/settings/integrations')\n );\n}\n\nfunction isProjectCreationPath(pathname: string, workspaceSlug: string) {\n return pathname === workspacePath(workspaceSlug, '/projects/new');\n}\n\nfunction isModelProviderOnboardingPath(pathname: string, workspaceSlug: string) {\n return pathname === workspacePath(workspaceSlug, '/model-provider');\n}\n\nfunction isAgentSettingsPath(pathname: string, workspaceSlug: string) {\n return pathname === workspacePath(workspaceSlug, '/settings/agents');\n}\n"],"names":["isModelProviderOnboardingDismissed","modelProviderConfigsQueryOptions","sourceConnectionsQueryOptions","projectExistenceQueryOptions","userWorkspacesQueryOptions","WorkspaceSetupLoadError","redirect","TRAILING_SLASHES_RE","loadWorkspaceSetupRoute","queryClient","workspaceId","workspaceSlug","pathname","workspace","fetchWorkspaceSummary","workspaceStatus","status","undefined","hideProjectNavigation","unavailable","assertNever","projects","fetchWorkspaceProjectExistence","normalizedPathname","normalizePath","length","isIntegrationsIndexPath","to","params","replace","sourceConnections","fetchWorkspaceSourceConnections","hasSourceConnection","isIntegrationSetupPath","isAgentSettingsPath","providerHandled","hasHandledModelProviderOnboarding","isModelProviderOnboardingPath","isProjectCreationPath","value","Error","JSON","stringify","result","fetchQuery","memberships","find","id","error","options","cached","getQueryData","queryKey","configs","workspacePath","suffix","basePath","startsWith"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/workspace-setup-route.ts"],"sourcesContent":["import {\n isModelProviderOnboardingDismissed,\n modelProviderCatalogQueryOptions,\n modelProviderConfigsQueryOptions,\n} from '@shipfox/client-agent';\nimport {\n type IntegrationConnection,\n sourceConnectionsQueryOptions,\n} from '@shipfox/client-integrations';\nimport {projectExistenceQueryOptions} from '@shipfox/client-projects';\nimport {\n userWorkspacesQueryOptions,\n WorkspaceSetupLoadError,\n type WorkspaceSetupRouteOptions,\n type WorkspaceSetupState,\n} from '@shipfox/client-shell/runtime';\nimport type {QueryClient} from '@tanstack/react-query';\nimport {redirect} from '@tanstack/react-router';\n\nconst TRAILING_SLASHES_RE = /\\/+$/u;\n\nexport type {WorkspaceSetupRouteOptions} from '@shipfox/client-shell/runtime';\n\nexport async function loadWorkspaceSetupRoute({\n queryClient,\n workspaceId,\n workspaceSlug,\n pathname,\n}: WorkspaceSetupRouteOptions): Promise<WorkspaceSetupState> {\n const workspace = await fetchWorkspaceSummary(queryClient, workspaceId);\n const workspaceStatus = workspace?.status;\n switch (workspaceStatus) {\n case undefined:\n case 'active':\n break;\n case 'suspended':\n case 'deleted':\n return {hideProjectNavigation: true, unavailable: true};\n default:\n return assertNever(workspaceStatus);\n }\n\n const projects = await fetchWorkspaceProjectExistence(queryClient, workspaceId);\n const normalizedPathname = normalizePath(pathname);\n\n if (projects.projects.length > 0) {\n if (isIntegrationsIndexPath(normalizedPathname, workspaceSlug)) {\n throw redirect({\n to: '/w/$workspaceSlug/settings/integrations',\n params: {workspaceSlug},\n replace: true,\n });\n }\n\n return {hideProjectNavigation: false};\n }\n\n const sourceConnections = await fetchWorkspaceSourceConnections(queryClient, workspaceId);\n const hasSourceConnection = sourceConnections.length > 0;\n\n if (!hasSourceConnection) {\n if (isIntegrationSetupPath(normalizedPathname, workspaceSlug)) {\n return {hideProjectNavigation: true};\n }\n\n throw redirect({\n to: '/w/$workspaceSlug/integrations',\n params: {workspaceSlug},\n replace: true,\n });\n }\n\n if (isAgentSettingsPath(normalizedPathname, workspaceSlug)) {\n return {hideProjectNavigation: true};\n }\n\n const providerHandled = await hasHandledModelProviderOnboarding(queryClient, workspaceId);\n if (!providerHandled) {\n if (isModelProviderOnboardingPath(normalizedPathname, workspaceSlug)) {\n return {hideProjectNavigation: true};\n }\n\n throw redirect({\n to: '/w/$workspaceSlug/model-provider',\n params: {workspaceSlug},\n replace: true,\n });\n }\n\n if (isProjectCreationPath(normalizedPathname, workspaceSlug)) {\n return {hideProjectNavigation: true};\n }\n\n throw redirect({\n to: '/w/$workspaceSlug/projects/new',\n params: {workspaceSlug},\n replace: true,\n });\n}\n\nfunction assertNever(value: never): never {\n throw new Error(`Unhandled workspace status: ${JSON.stringify(value)}`);\n}\n\nasync function fetchWorkspaceSummary(queryClient: QueryClient, workspaceId: string) {\n try {\n const result = await queryClient.fetchQuery(userWorkspacesQueryOptions());\n return result.memberships.find((workspace) => workspace.id === workspaceId);\n } catch (error) {\n throw new WorkspaceSetupLoadError(error);\n }\n}\n\nasync function fetchWorkspaceProjectExistence(queryClient: QueryClient, workspaceId: string) {\n const options = projectExistenceQueryOptions(workspaceId);\n\n try {\n return await queryClient.fetchQuery(options);\n } catch (error) {\n const cached = queryClient.getQueryData<{projects: unknown[]}>(options.queryKey);\n if (cached !== undefined) return cached;\n throw new WorkspaceSetupLoadError(error);\n }\n}\n\nasync function fetchWorkspaceSourceConnections(queryClient: QueryClient, workspaceId: string) {\n const options = sourceConnectionsQueryOptions(workspaceId);\n\n try {\n return await queryClient.fetchQuery(options);\n } catch (error) {\n const cached = queryClient.getQueryData<IntegrationConnection[]>(options.queryKey);\n if (cached !== undefined) return cached;\n throw new WorkspaceSetupLoadError(error);\n }\n}\n\nasync function hasHandledModelProviderOnboarding(\n queryClient: QueryClient,\n workspaceId: string,\n): Promise<boolean> {\n if (isModelProviderOnboardingDismissed(workspaceId)) return true;\n\n const catalogOptions = modelProviderCatalogQueryOptions();\n const configOptions = modelProviderConfigsQueryOptions(workspaceId);\n const [catalogResult, configsResult] = await Promise.allSettled([\n queryClient.fetchQuery(catalogOptions),\n queryClient.fetchQuery(configOptions),\n ]);\n\n if (\n catalogResult.status === 'fulfilled' &&\n catalogResult.value.workspaceProviders === 'disabled'\n ) {\n return true;\n }\n\n if (configsResult.status === 'fulfilled') {\n const configs = configsResult.value;\n return configs.configs.length > 0;\n }\n\n const cached = queryClient.getQueryData<{configs: unknown[]}>(configOptions.queryKey);\n return cached?.configs.length !== 0;\n}\n\nfunction normalizePath(pathname: string) {\n if (pathname === '/') return pathname;\n return pathname.replace(TRAILING_SLASHES_RE, '');\n}\n\nfunction workspacePath(workspaceSlug: string, suffix: string) {\n return `/w/${workspaceSlug}${suffix}`;\n}\n\nfunction isIntegrationsIndexPath(pathname: string, workspaceSlug: string) {\n return pathname === workspacePath(workspaceSlug, '/integrations');\n}\n\nfunction isIntegrationSetupPath(pathname: string, workspaceSlug: string) {\n const basePath = workspacePath(workspaceSlug, '/integrations');\n return (\n pathname === basePath ||\n pathname.startsWith(`${basePath}/`) ||\n pathname === workspacePath(workspaceSlug, '/settings/integrations')\n );\n}\n\nfunction isProjectCreationPath(pathname: string, workspaceSlug: string) {\n return pathname === workspacePath(workspaceSlug, '/projects/new');\n}\n\nfunction isModelProviderOnboardingPath(pathname: string, workspaceSlug: string) {\n return pathname === workspacePath(workspaceSlug, '/model-provider');\n}\n\nfunction isAgentSettingsPath(pathname: string, workspaceSlug: string) {\n return pathname === workspacePath(workspaceSlug, '/settings/agents');\n}\n"],"names":["isModelProviderOnboardingDismissed","modelProviderCatalogQueryOptions","modelProviderConfigsQueryOptions","sourceConnectionsQueryOptions","projectExistenceQueryOptions","userWorkspacesQueryOptions","WorkspaceSetupLoadError","redirect","TRAILING_SLASHES_RE","loadWorkspaceSetupRoute","queryClient","workspaceId","workspaceSlug","pathname","workspace","fetchWorkspaceSummary","workspaceStatus","status","undefined","hideProjectNavigation","unavailable","assertNever","projects","fetchWorkspaceProjectExistence","normalizedPathname","normalizePath","length","isIntegrationsIndexPath","to","params","replace","sourceConnections","fetchWorkspaceSourceConnections","hasSourceConnection","isIntegrationSetupPath","isAgentSettingsPath","providerHandled","hasHandledModelProviderOnboarding","isModelProviderOnboardingPath","isProjectCreationPath","value","Error","JSON","stringify","result","fetchQuery","memberships","find","id","error","options","cached","getQueryData","queryKey","catalogOptions","configOptions","catalogResult","configsResult","Promise","allSettled","workspaceProviders","configs","workspacePath","suffix","basePath","startsWith"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@shipfox/client-onboarding",
3
3
  "license": "MIT",
4
- "version": "22.0.2",
4
+ "version": "22.0.3",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/ShipfoxHQ/shipfox.git",
@@ -18,10 +18,10 @@
18
18
  },
19
19
  "dependencies": {
20
20
  "@swc/helpers": "^0.5.17",
21
- "@shipfox/client-agent": "22.0.2",
22
- "@shipfox/client-integrations": "22.0.2",
23
- "@shipfox/client-projects": "22.0.2",
24
- "@shipfox/client-shell": "22.0.2"
21
+ "@shipfox/client-agent": "22.0.3",
22
+ "@shipfox/client-integrations": "22.0.3",
23
+ "@shipfox/client-projects": "22.0.3",
24
+ "@shipfox/client-shell": "22.0.3"
25
25
  },
26
26
  "peerDependencies": {
27
27
  "@tanstack/react-query": "^5.101.0",
@@ -82,6 +82,7 @@ interface SetupFetchOptions {
82
82
  projectsFail?: boolean;
83
83
  connectionsFail?: boolean;
84
84
  providerConfigsFail?: boolean;
85
+ workspaceProviders?: 'enabled' | 'disabled';
85
86
  projectsPending?: boolean;
86
87
  workspaceStatus?: 'active' | 'suspended' | 'deleted';
87
88
  }
@@ -95,6 +96,7 @@ function setupFetch(options: SetupFetchOptions = {}) {
95
96
  projectsFail = false,
96
97
  connectionsFail = false,
97
98
  providerConfigsFail = false,
99
+ workspaceProviders,
98
100
  projectsPending = false,
99
101
  workspaceStatus = 'active',
100
102
  } = options;
@@ -140,6 +142,14 @@ function setupFetch(options: SetupFetchOptions = {}) {
140
142
  }),
141
143
  );
142
144
  }
145
+ if (url.endsWith('/agent/model-provider-catalog')) {
146
+ return Promise.resolve(
147
+ jsonResponse({
148
+ providers: [],
149
+ ...(workspaceProviders === undefined ? {} : {workspace_providers: workspaceProviders}),
150
+ }),
151
+ );
152
+ }
143
153
  return Promise.resolve(jsonResponse({}, {status: 404}));
144
154
  });
145
155
  }
@@ -353,6 +363,20 @@ describe('workspace setup route hook', () => {
353
363
  expect(screen.getByTestId('project-navigation')).toHaveTextContent('hidden');
354
364
  });
355
365
 
366
+ test('skips provider onboarding when workspace providers are managed by the instance', async () => {
367
+ const fetchImpl = setupFetch({
368
+ connections: [sourceConnection()],
369
+ providerConfigs: [],
370
+ defaultProviderId: null,
371
+ workspaceProviders: 'disabled',
372
+ });
373
+
374
+ renderSetupRoute(`/w/${WORKSPACE_SLUG}/integrations`, fetchImpl);
375
+
376
+ expect(await screen.findByText('Create project')).toBeInTheDocument();
377
+ expect(calledUrls(fetchImpl).some((url) => url.endsWith('/agent/model-providers'))).toBe(true);
378
+ });
379
+
356
380
  test('keeps the provider onboarding route available while provider setup is pending', async () => {
357
381
  renderSetupRoute(
358
382
  `/w/${WORKSPACE_SLUG}/model-provider`,
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  isModelProviderOnboardingDismissed,
3
+ modelProviderCatalogQueryOptions,
3
4
  modelProviderConfigsQueryOptions,
4
5
  } from '@shipfox/client-agent';
5
6
  import {
@@ -140,14 +141,27 @@ async function hasHandledModelProviderOnboarding(
140
141
  ): Promise<boolean> {
141
142
  if (isModelProviderOnboardingDismissed(workspaceId)) return true;
142
143
 
143
- const options = modelProviderConfigsQueryOptions(workspaceId);
144
- try {
145
- const configs = await queryClient.fetchQuery(options);
144
+ const catalogOptions = modelProviderCatalogQueryOptions();
145
+ const configOptions = modelProviderConfigsQueryOptions(workspaceId);
146
+ const [catalogResult, configsResult] = await Promise.allSettled([
147
+ queryClient.fetchQuery(catalogOptions),
148
+ queryClient.fetchQuery(configOptions),
149
+ ]);
150
+
151
+ if (
152
+ catalogResult.status === 'fulfilled' &&
153
+ catalogResult.value.workspaceProviders === 'disabled'
154
+ ) {
155
+ return true;
156
+ }
157
+
158
+ if (configsResult.status === 'fulfilled') {
159
+ const configs = configsResult.value;
146
160
  return configs.configs.length > 0;
147
- } catch {
148
- const cached = queryClient.getQueryData<{configs: unknown[]}>(options.queryKey);
149
- return cached?.configs.length !== 0;
150
161
  }
162
+
163
+ const cached = queryClient.getQueryData<{configs: unknown[]}>(configOptions.queryKey);
164
+ return cached?.configs.length !== 0;
151
165
  }
152
166
 
153
167
  function normalizePath(pathname: string) {