@shipfox/client-shell 12.0.2 → 13.0.0

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.
Files changed (70) hide show
  1. package/dist/components/main-layout.js +2 -2
  2. package/dist/components/main-layout.js.map +1 -1
  3. package/dist/components/settings-nav.d.ts +2 -1
  4. package/dist/components/settings-nav.d.ts.map +1 -1
  5. package/dist/components/settings-nav.js +17 -13
  6. package/dist/components/settings-nav.js.map +1 -1
  7. package/dist/components/workspace-crumb.js +2 -2
  8. package/dist/components/workspace-crumb.js.map +1 -1
  9. package/dist/components/workspace-switcher.d.ts.map +1 -1
  10. package/dist/components/workspace-switcher.js +4 -2
  11. package/dist/components/workspace-switcher.js.map +1 -1
  12. package/dist/compose/compose-routes.d.ts.map +1 -1
  13. package/dist/compose/compose-routes.js +4 -1
  14. package/dist/compose/compose-routes.js.map +1 -1
  15. package/dist/compose/validate-registries.d.ts.map +1 -1
  16. package/dist/compose/validate-registries.js +1 -1
  17. package/dist/compose/validate-registries.js.map +1 -1
  18. package/dist/contract.d.ts +2 -1
  19. package/dist/contract.d.ts.map +1 -1
  20. package/dist/contract.js.map +1 -1
  21. package/dist/core/session.d.ts +1 -0
  22. package/dist/core/session.d.ts.map +1 -1
  23. package/dist/core/session.js.map +1 -1
  24. package/dist/hooks/api/session-auth.d.ts.map +1 -1
  25. package/dist/hooks/api/session-auth.js +1 -0
  26. package/dist/hooks/api/session-auth.js.map +1 -1
  27. package/dist/runtime/active-workspace.js +3 -3
  28. package/dist/runtime/active-workspace.js.map +1 -1
  29. package/dist/runtime/anchor-paths.d.ts +14 -4
  30. package/dist/runtime/anchor-paths.d.ts.map +1 -1
  31. package/dist/runtime/anchor-paths.js +57 -4
  32. package/dist/runtime/anchor-paths.js.map +1 -1
  33. package/dist/runtime/anchors.d.ts +9 -6
  34. package/dist/runtime/anchors.d.ts.map +1 -1
  35. package/dist/runtime/anchors.js +85 -42
  36. package/dist/runtime/anchors.js.map +1 -1
  37. package/dist/runtime/assemble-route-tree.d.ts.map +1 -1
  38. package/dist/runtime/assemble-route-tree.js +7 -2
  39. package/dist/runtime/assemble-route-tree.js.map +1 -1
  40. package/dist/runtime/chrome-context.d.ts +2 -1
  41. package/dist/runtime/chrome-context.d.ts.map +1 -1
  42. package/dist/runtime/chrome-context.js.map +1 -1
  43. package/dist/runtime/compose-client-app.d.ts.map +1 -1
  44. package/dist/runtime/compose-client-app.js +5 -3
  45. package/dist/runtime/compose-client-app.js.map +1 -1
  46. package/dist/runtime/index.d.ts +1 -0
  47. package/dist/runtime/index.d.ts.map +1 -1
  48. package/dist/runtime/index.js +1 -0
  49. package/dist/runtime/index.js.map +1 -1
  50. package/dist/runtime/registries.js +4 -1
  51. package/dist/runtime/registries.js.map +1 -1
  52. package/dist/runtime/route-inputs.d.ts +3 -3
  53. package/dist/runtime/route-inputs.d.ts.map +1 -1
  54. package/dist/runtime/route-inputs.js +9 -9
  55. package/dist/runtime/route-inputs.js.map +1 -1
  56. package/dist/runtime/router-context.d.ts +7 -0
  57. package/dist/runtime/router-context.d.ts.map +1 -1
  58. package/dist/runtime/router-context.js.map +1 -1
  59. package/dist/runtime/search-serialization.d.ts +26 -0
  60. package/dist/runtime/search-serialization.d.ts.map +1 -0
  61. package/dist/runtime/search-serialization.js +78 -0
  62. package/dist/runtime/search-serialization.js.map +1 -0
  63. package/dist/runtime/workspace-setup.d.ts +1 -0
  64. package/dist/runtime/workspace-setup.d.ts.map +1 -1
  65. package/dist/runtime/workspace-setup.js.map +1 -1
  66. package/dist/tsconfig.test.tsbuildinfo +1 -1
  67. package/dist/vite/generate.d.ts.map +1 -1
  68. package/dist/vite/generate.js +12 -3
  69. package/dist/vite/generate.js.map +1 -1
  70. package/package.json +6 -6
@@ -1 +1 @@
1
- {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/vite/generate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,cAAc,EAAE,aAAa,EAAC,MAAM,4BAA4B,CAAC;AAC9E,OAAO,KAAK,EAAC,WAAW,EAAiB,oBAAoB,EAAC,MAAM,cAAc,CAAC;AAGnF,MAAM,WAAW,wBAAwB;IACvC,OAAO,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IACpC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;IACjC,UAAU,EAAE,SAAS,WAAW,EAAE,CAAC;IACnC,gBAAgB,EAAE,SAAS,oBAAoB,EAAE,CAAC;CACnD;AAoED,wBAAgB,iBAAiB,CAAC,EAChC,OAAY,EACZ,MAAM,EACN,UAAU,EACV,gBAAgB,GACjB,EAAE,wBAAwB,GAAG,MAAM,CA8GnC"}
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/vite/generate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,cAAc,EAAE,aAAa,EAAC,MAAM,4BAA4B,CAAC;AAC9E,OAAO,KAAK,EAAC,WAAW,EAAiB,oBAAoB,EAAC,MAAM,cAAc,CAAC;AAGnF,MAAM,WAAW,wBAAwB;IACvC,OAAO,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IACpC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;IACjC,UAAU,EAAE,SAAS,WAAW,EAAE,CAAC;IACnC,gBAAgB,EAAE,SAAS,oBAAoB,EAAE,CAAC;CACnD;AA0ED,wBAAgB,iBAAiB,CAAC,EAChC,OAAY,EACZ,MAAM,EACN,UAAU,EACV,gBAAgB,GACjB,EAAE,wBAAwB,GAAG,MAAM,CAwHnC"}
@@ -10,7 +10,8 @@ function isShellAnchor(parent) {
10
10
  'root',
11
11
  'workspaceLayout',
12
12
  'projectLayout',
13
- 'workspaceSettings'
13
+ 'workspaceSettings',
14
+ 'projectSettings'
14
15
  ].includes(parent);
15
16
  }
16
17
  function orderedLayouts(layouts) {
@@ -108,12 +109,17 @@ export function generateAppModule({ layouts = [], routes, navigation, settingsSe
108
109
  ].filter(Boolean).join(',\n ');
109
110
  const projectChildren = [
110
111
  routeNames(routes, 'projectLayout'),
111
- ...layoutTreeNames(generatedLayouts, 'projectLayout')
112
+ ...layoutTreeNames(generatedLayouts, 'projectLayout'),
113
+ 'projectSettings'
112
114
  ].filter(Boolean).join(',\n ');
113
115
  const workspaceSettingsChildren = [
114
116
  routeNames(routes, 'workspaceSettings'),
115
117
  ...layoutTreeNames(generatedLayouts, 'workspaceSettings')
116
118
  ].filter(Boolean).join(',\n ');
119
+ const projectSettingsChildren = [
120
+ routeNames(routes, 'projectSettings'),
121
+ ...layoutTreeNames(generatedLayouts, 'projectSettings')
122
+ ].filter(Boolean).join(',\n ');
117
123
  const workspaceChildren = [
118
124
  routeNames(routes, 'workspaceLayout'),
119
125
  ...layoutTreeNames(generatedLayouts, 'workspaceLayout'),
@@ -124,7 +130,7 @@ export function generateAppModule({ layouts = [], routes, navigation, settingsSe
124
130
  // biome-ignore-all format: generated code has stable, reviewable output.
125
131
  // biome-ignore-all assist/source/organizeImports: generated imports follow route order.
126
132
  import {createRoute, createRouter} from '@tanstack/react-router';
127
- import {buildAnchorSkeleton, isRouteImpl, type RouteImpl, type RouterContext} from '@shipfox/client-shell/runtime';
133
+ import {buildAnchorSkeleton, isRouteImpl, parseAppSearch, stringifyAppSearch, type RouteImpl, type RouterContext} from '@shipfox/client-shell/runtime';
128
134
  ${imports}
129
135
 
130
136
  function routeOptions<T extends RouteImpl>(routeImpl: T, impl: string, path: string): T['options'] {
@@ -141,6 +147,7 @@ const skeleton = buildAnchorSkeleton({
141
147
 
142
148
  ${declarations}
143
149
 
150
+ const projectSettings = skeleton.projectSettings.addChildren([${projectSettingsChildren}]);
144
151
  const projectLayout = skeleton.projectLayout.addChildren([${projectChildren}]);
145
152
  const workspaceSettings = skeleton.workspaceSettings.addChildren([${workspaceSettingsChildren}]);
146
153
  const workspaceLayout = skeleton.workspaceLayout.addChildren([
@@ -155,6 +162,8 @@ export const router = createRouter({
155
162
  routeTree,
156
163
  context: {auth: undefined, queryClient: undefined} satisfies RouterContext,
157
164
  scrollRestoration: true,
165
+ parseSearch: parseAppSearch,
166
+ stringifySearch: stringifyAppSearch,
158
167
  });
159
168
 
160
169
  declare module '@tanstack/react-router' {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/vite/generate.ts"],"sourcesContent":["import type {ComposedLayout, ComposedRoute} from '#compose/compose-routes.js';\nimport type {NavTabEntry, RouteParentId, SettingsSectionEntry} from '#contract.js';\nimport {routePathForParent} from '#runtime/anchor-paths.js';\n\nexport interface GenerateAppModuleOptions {\n layouts?: readonly ComposedLayout[];\n routes: readonly ComposedRoute[];\n navigation: readonly NavTabEntry[];\n settingsSections: readonly SettingsSectionEntry[];\n}\n\nfunction literal(value: unknown): string {\n return JSON.stringify(value, undefined, 2);\n}\n\nfunction indentedLiteral(value: unknown, indentation: number): string {\n return literal(value).replaceAll('\\n', `\\n${' '.repeat(indentation)}`);\n}\n\nfunction isShellAnchor(parent: RouteParentId): boolean {\n return ['root', 'workspaceLayout', 'projectLayout', 'workspaceSettings'].includes(parent);\n}\n\nfunction orderedLayouts(layouts: readonly ComposedLayout[]): ComposedLayout[] {\n const byId = new Map(layouts.map((layout) => [layout.id, layout]));\n const ordered: ComposedLayout[] = [];\n const visiting = new Set<string>();\n const visited = new Set<string>();\n\n function visit(layout: ComposedLayout): void {\n if (visited.has(layout.id)) return;\n if (!isShellAnchor(layout.parent)) {\n if (visiting.has(layout.id)) {\n throw new Error(`Layout \"${layout.id}\" has a cyclic parent reference.`);\n }\n const parent = byId.get(layout.parent);\n if (!parent) {\n throw new Error(`Layout \"${layout.id}\" targets missing layout parent \"${layout.parent}\".`);\n }\n visiting.add(layout.id);\n visit(parent);\n visiting.delete(layout.id);\n }\n visited.add(layout.id);\n ordered.push(layout);\n }\n\n for (const layout of layouts) visit(layout);\n return ordered;\n}\n\nfunction routeNames(routes: readonly ComposedRoute[], parent: RouteParentId): string {\n return routes\n .map((route, index) => ({route, index}))\n .filter(({route}) => route.parent === parent)\n .map(({index}) => `route${index}`)\n .join(', ');\n}\n\nfunction layoutTreeNames(layouts: readonly ComposedLayout[], parent: RouteParentId): string[] {\n return layouts\n .map((layout, index) => ({layout, index}))\n .filter(({layout}) => layout.parent === parent)\n .map(({index}) => `layout${index}Tree`);\n}\n\nfunction parentExpression(\n parent: RouteParentId,\n layoutIndexes: ReadonlyMap<string, number>,\n): string {\n if (parent === 'root') return 'skeleton.rootRoute';\n if (isShellAnchor(parent)) return `skeleton.${parent}`;\n const index = layoutIndexes.get(parent);\n if (index === undefined) throw new Error(`Missing generated layout parent \"${parent}\".`);\n return `layout${index}`;\n}\n\nexport function generateAppModule({\n layouts = [],\n routes,\n navigation,\n settingsSections,\n}: GenerateAppModuleOptions): string {\n const generatedLayouts = orderedLayouts(layouts);\n const layoutIndexes = new Map(generatedLayouts.map((layout, index) => [layout.id, index]));\n const layoutPaths = new Map(generatedLayouts.map((layout) => [layout.id, layout.path]));\n const imports = [\n ...generatedLayouts.map(\n (layout, index) => `import * as layout${index}Module from ${literal(layout.impl)};`,\n ),\n ...routes.map((route, index) => `import * as route${index}Module from ${literal(route.impl)};`),\n ].join('\\n');\n const layoutDeclarations = generatedLayouts\n .map(\n (layout, index) => `const layout${index} = createRoute({\n getParentRoute: () => ${parentExpression(layout.parent, layoutIndexes)},\n path: ${literal(routePathForParent(layout.parent, layout.path, layoutPaths))},\n ...routeOptions(layout${index}Module.default, ${literal(layout.impl)}, ${literal(layout.path)}),\n});`,\n )\n .join('\\n\\n');\n const routeDeclarations = routes\n .map(\n (route, index) => `const route${index} = createRoute({\n getParentRoute: () => ${parentExpression(route.parent, layoutIndexes)},\n path: ${literal(routePathForParent(route.parent, route.path, layoutPaths))},\n ...routeOptions(route${index}Module.default, ${literal(route.impl)}, ${literal(route.path)}),\n});`,\n )\n .join('\\n\\n');\n const layoutTreeDeclarations = generatedLayouts\n .map((layout, index) => ({layout, index}))\n .reverse()\n .map(({layout, index}) => {\n const routeChildren = routeNames(routes, layout.id);\n const children = [routeChildren, ...layoutTreeNames(generatedLayouts, layout.id)]\n .filter(Boolean)\n .join(',\\n ');\n return `const layout${index}Tree = layout${index}.addChildren([${children}]);`;\n })\n .join('\\n');\n const declarations = [layoutDeclarations, routeDeclarations, layoutTreeDeclarations]\n .filter(Boolean)\n .join('\\n\\n');\n const rootRoutes = routeNames(routes, 'root');\n const rootChildren = [rootRoutes, ...layoutTreeNames(generatedLayouts, 'root'), 'workspaceLayout']\n .filter(Boolean)\n .join(',\\n ');\n const projectChildren = [\n routeNames(routes, 'projectLayout'),\n ...layoutTreeNames(generatedLayouts, 'projectLayout'),\n ]\n .filter(Boolean)\n .join(',\\n ');\n const workspaceSettingsChildren = [\n routeNames(routes, 'workspaceSettings'),\n ...layoutTreeNames(generatedLayouts, 'workspaceSettings'),\n ]\n .filter(Boolean)\n .join(',\\n ');\n const workspaceChildren = [\n routeNames(routes, 'workspaceLayout'),\n ...layoutTreeNames(generatedLayouts, 'workspaceLayout'),\n 'projectLayout',\n 'workspaceSettings',\n ]\n .filter(Boolean)\n .join(',\\n ');\n\n return `// GENERATED by @shipfox/client-shell/vite. Do not edit.\n// biome-ignore-all format: generated code has stable, reviewable output.\n// biome-ignore-all assist/source/organizeImports: generated imports follow route order.\nimport {createRoute, createRouter} from '@tanstack/react-router';\nimport {buildAnchorSkeleton, isRouteImpl, type RouteImpl, type RouterContext} from '@shipfox/client-shell/runtime';\n${imports}\n\nfunction routeOptions<T extends RouteImpl>(routeImpl: T, impl: string, path: string): T['options'] {\n if (!isRouteImpl(routeImpl)) {\n throw new TypeError(\\`Route implementation \"\\${impl}\" for \"\\${path}\" must export default defineRoute(...).\\`);\n }\n return routeImpl.options;\n}\n\nconst skeleton = buildAnchorSkeleton({\n navigation: ${indentedLiteral(navigation, 2)},\n settingsSections: ${indentedLiteral(settingsSections, 2)},\n});\n\n${declarations}\n\nconst projectLayout = skeleton.projectLayout.addChildren([${projectChildren}]);\nconst workspaceSettings = skeleton.workspaceSettings.addChildren([${workspaceSettingsChildren}]);\nconst workspaceLayout = skeleton.workspaceLayout.addChildren([\n ${workspaceChildren},\n]);\n\nexport const routeTree = skeleton.rootRoute.addChildren([\n ${rootChildren},\n]);\n\nexport const router = createRouter({\n routeTree,\n context: {auth: undefined, queryClient: undefined} satisfies RouterContext,\n scrollRestoration: true,\n});\n\ndeclare module '@tanstack/react-router' {\n interface Register {\n router: typeof router;\n }\n}\n`;\n}\n"],"names":["routePathForParent","literal","value","JSON","stringify","undefined","indentedLiteral","indentation","replaceAll","repeat","isShellAnchor","parent","includes","orderedLayouts","layouts","byId","Map","map","layout","id","ordered","visiting","Set","visited","visit","has","Error","get","add","delete","push","routeNames","routes","route","index","filter","join","layoutTreeNames","parentExpression","layoutIndexes","generateAppModule","navigation","settingsSections","generatedLayouts","layoutPaths","path","imports","impl","layoutDeclarations","routeDeclarations","layoutTreeDeclarations","reverse","routeChildren","children","Boolean","declarations","rootRoutes","rootChildren","projectChildren","workspaceSettingsChildren","workspaceChildren"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/vite/generate.ts"],"sourcesContent":["import type {ComposedLayout, ComposedRoute} from '#compose/compose-routes.js';\nimport type {NavTabEntry, RouteParentId, SettingsSectionEntry} from '#contract.js';\nimport {routePathForParent} from '#runtime/anchor-paths.js';\n\nexport interface GenerateAppModuleOptions {\n layouts?: readonly ComposedLayout[];\n routes: readonly ComposedRoute[];\n navigation: readonly NavTabEntry[];\n settingsSections: readonly SettingsSectionEntry[];\n}\n\nfunction literal(value: unknown): string {\n return JSON.stringify(value, undefined, 2);\n}\n\nfunction indentedLiteral(value: unknown, indentation: number): string {\n return literal(value).replaceAll('\\n', `\\n${' '.repeat(indentation)}`);\n}\n\nfunction isShellAnchor(parent: RouteParentId): boolean {\n return [\n 'root',\n 'workspaceLayout',\n 'projectLayout',\n 'workspaceSettings',\n 'projectSettings',\n ].includes(parent);\n}\n\nfunction orderedLayouts(layouts: readonly ComposedLayout[]): ComposedLayout[] {\n const byId = new Map(layouts.map((layout) => [layout.id, layout]));\n const ordered: ComposedLayout[] = [];\n const visiting = new Set<string>();\n const visited = new Set<string>();\n\n function visit(layout: ComposedLayout): void {\n if (visited.has(layout.id)) return;\n if (!isShellAnchor(layout.parent)) {\n if (visiting.has(layout.id)) {\n throw new Error(`Layout \"${layout.id}\" has a cyclic parent reference.`);\n }\n const parent = byId.get(layout.parent);\n if (!parent) {\n throw new Error(`Layout \"${layout.id}\" targets missing layout parent \"${layout.parent}\".`);\n }\n visiting.add(layout.id);\n visit(parent);\n visiting.delete(layout.id);\n }\n visited.add(layout.id);\n ordered.push(layout);\n }\n\n for (const layout of layouts) visit(layout);\n return ordered;\n}\n\nfunction routeNames(routes: readonly ComposedRoute[], parent: RouteParentId): string {\n return routes\n .map((route, index) => ({route, index}))\n .filter(({route}) => route.parent === parent)\n .map(({index}) => `route${index}`)\n .join(', ');\n}\n\nfunction layoutTreeNames(layouts: readonly ComposedLayout[], parent: RouteParentId): string[] {\n return layouts\n .map((layout, index) => ({layout, index}))\n .filter(({layout}) => layout.parent === parent)\n .map(({index}) => `layout${index}Tree`);\n}\n\nfunction parentExpression(\n parent: RouteParentId,\n layoutIndexes: ReadonlyMap<string, number>,\n): string {\n if (parent === 'root') return 'skeleton.rootRoute';\n if (isShellAnchor(parent)) return `skeleton.${parent}`;\n const index = layoutIndexes.get(parent);\n if (index === undefined) throw new Error(`Missing generated layout parent \"${parent}\".`);\n return `layout${index}`;\n}\n\nexport function generateAppModule({\n layouts = [],\n routes,\n navigation,\n settingsSections,\n}: GenerateAppModuleOptions): string {\n const generatedLayouts = orderedLayouts(layouts);\n const layoutIndexes = new Map(generatedLayouts.map((layout, index) => [layout.id, index]));\n const layoutPaths = new Map(generatedLayouts.map((layout) => [layout.id, layout.path]));\n const imports = [\n ...generatedLayouts.map(\n (layout, index) => `import * as layout${index}Module from ${literal(layout.impl)};`,\n ),\n ...routes.map((route, index) => `import * as route${index}Module from ${literal(route.impl)};`),\n ].join('\\n');\n const layoutDeclarations = generatedLayouts\n .map(\n (layout, index) => `const layout${index} = createRoute({\n getParentRoute: () => ${parentExpression(layout.parent, layoutIndexes)},\n path: ${literal(routePathForParent(layout.parent, layout.path, layoutPaths))},\n ...routeOptions(layout${index}Module.default, ${literal(layout.impl)}, ${literal(layout.path)}),\n});`,\n )\n .join('\\n\\n');\n const routeDeclarations = routes\n .map(\n (route, index) => `const route${index} = createRoute({\n getParentRoute: () => ${parentExpression(route.parent, layoutIndexes)},\n path: ${literal(routePathForParent(route.parent, route.path, layoutPaths))},\n ...routeOptions(route${index}Module.default, ${literal(route.impl)}, ${literal(route.path)}),\n});`,\n )\n .join('\\n\\n');\n const layoutTreeDeclarations = generatedLayouts\n .map((layout, index) => ({layout, index}))\n .reverse()\n .map(({layout, index}) => {\n const routeChildren = routeNames(routes, layout.id);\n const children = [routeChildren, ...layoutTreeNames(generatedLayouts, layout.id)]\n .filter(Boolean)\n .join(',\\n ');\n return `const layout${index}Tree = layout${index}.addChildren([${children}]);`;\n })\n .join('\\n');\n const declarations = [layoutDeclarations, routeDeclarations, layoutTreeDeclarations]\n .filter(Boolean)\n .join('\\n\\n');\n const rootRoutes = routeNames(routes, 'root');\n const rootChildren = [rootRoutes, ...layoutTreeNames(generatedLayouts, 'root'), 'workspaceLayout']\n .filter(Boolean)\n .join(',\\n ');\n const projectChildren = [\n routeNames(routes, 'projectLayout'),\n ...layoutTreeNames(generatedLayouts, 'projectLayout'),\n 'projectSettings',\n ]\n .filter(Boolean)\n .join(',\\n ');\n const workspaceSettingsChildren = [\n routeNames(routes, 'workspaceSettings'),\n ...layoutTreeNames(generatedLayouts, 'workspaceSettings'),\n ]\n .filter(Boolean)\n .join(',\\n ');\n const projectSettingsChildren = [\n routeNames(routes, 'projectSettings'),\n ...layoutTreeNames(generatedLayouts, 'projectSettings'),\n ]\n .filter(Boolean)\n .join(',\\n ');\n const workspaceChildren = [\n routeNames(routes, 'workspaceLayout'),\n ...layoutTreeNames(generatedLayouts, 'workspaceLayout'),\n 'projectLayout',\n 'workspaceSettings',\n ]\n .filter(Boolean)\n .join(',\\n ');\n\n return `// GENERATED by @shipfox/client-shell/vite. Do not edit.\n// biome-ignore-all format: generated code has stable, reviewable output.\n// biome-ignore-all assist/source/organizeImports: generated imports follow route order.\nimport {createRoute, createRouter} from '@tanstack/react-router';\nimport {buildAnchorSkeleton, isRouteImpl, parseAppSearch, stringifyAppSearch, type RouteImpl, type RouterContext} from '@shipfox/client-shell/runtime';\n${imports}\n\nfunction routeOptions<T extends RouteImpl>(routeImpl: T, impl: string, path: string): T['options'] {\n if (!isRouteImpl(routeImpl)) {\n throw new TypeError(\\`Route implementation \"\\${impl}\" for \"\\${path}\" must export default defineRoute(...).\\`);\n }\n return routeImpl.options;\n}\n\nconst skeleton = buildAnchorSkeleton({\n navigation: ${indentedLiteral(navigation, 2)},\n settingsSections: ${indentedLiteral(settingsSections, 2)},\n});\n\n${declarations}\n\nconst projectSettings = skeleton.projectSettings.addChildren([${projectSettingsChildren}]);\nconst projectLayout = skeleton.projectLayout.addChildren([${projectChildren}]);\nconst workspaceSettings = skeleton.workspaceSettings.addChildren([${workspaceSettingsChildren}]);\nconst workspaceLayout = skeleton.workspaceLayout.addChildren([\n ${workspaceChildren},\n]);\n\nexport const routeTree = skeleton.rootRoute.addChildren([\n ${rootChildren},\n]);\n\nexport const router = createRouter({\n routeTree,\n context: {auth: undefined, queryClient: undefined} satisfies RouterContext,\n scrollRestoration: true,\n parseSearch: parseAppSearch,\n stringifySearch: stringifyAppSearch,\n});\n\ndeclare module '@tanstack/react-router' {\n interface Register {\n router: typeof router;\n }\n}\n`;\n}\n"],"names":["routePathForParent","literal","value","JSON","stringify","undefined","indentedLiteral","indentation","replaceAll","repeat","isShellAnchor","parent","includes","orderedLayouts","layouts","byId","Map","map","layout","id","ordered","visiting","Set","visited","visit","has","Error","get","add","delete","push","routeNames","routes","route","index","filter","join","layoutTreeNames","parentExpression","layoutIndexes","generateAppModule","navigation","settingsSections","generatedLayouts","layoutPaths","path","imports","impl","layoutDeclarations","routeDeclarations","layoutTreeDeclarations","reverse","routeChildren","children","Boolean","declarations","rootRoutes","rootChildren","projectChildren","workspaceSettingsChildren","projectSettingsChildren","workspaceChildren"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@shipfox/client-shell",
3
3
  "license": "MIT",
4
- "version": "12.0.2",
4
+ "version": "13.0.0",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/ShipfoxHQ/shipfox.git",
@@ -38,12 +38,12 @@
38
38
  "@tanstack/router-core": "^1.171.13",
39
39
  "tsx": "^4.22.4",
40
40
  "framer-motion": "^12.23.24",
41
- "@shipfox/api-auth-dto": "10.2.0",
41
+ "@shipfox/api-auth-dto": "12.0.0",
42
+ "@shipfox/api-workspaces-dto": "12.0.0",
42
43
  "@shipfox/client-api": "6.0.1",
43
- "@shipfox/client-config": "6.0.2",
44
- "@shipfox/api-workspaces-dto": "11.0.0",
45
- "@shipfox/client-ui": "6.0.2",
46
- "@shipfox/react-ui": "0.3.7"
44
+ "@shipfox/client-config": "13.0.0",
45
+ "@shipfox/client-ui": "13.0.0",
46
+ "@shipfox/react-ui": "0.4.0"
47
47
  },
48
48
  "peerDependencies": {
49
49
  "@storybook/react": "^10.4.6",