@shipfox/client-shell 17.0.0 → 21.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.
- package/dist/components/main-layout.d.ts +2 -1
- package/dist/components/main-layout.d.ts.map +1 -1
- package/dist/components/main-layout.js +10 -7
- package/dist/components/main-layout.js.map +1 -1
- package/dist/runtime/anchors.d.ts.map +1 -1
- package/dist/runtime/anchors.js +6 -0
- package/dist/runtime/anchors.js.map +1 -1
- package/dist/runtime/assemble-route-tree.d.ts.map +1 -1
- package/dist/runtime/assemble-route-tree.js +3 -0
- package/dist/runtime/assemble-route-tree.js.map +1 -1
- package/dist/runtime/define-route.d.ts +5 -1
- package/dist/runtime/define-route.d.ts.map +1 -1
- package/dist/runtime/define-route.js.map +1 -1
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +1 -0
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/route-frame.d.ts +9 -0
- package/dist/runtime/route-frame.d.ts.map +1 -0
- package/dist/runtime/route-frame.js +22 -0
- package/dist/runtime/route-frame.js.map +1 -0
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/dist/vite/generate.d.ts.map +1 -1
- package/dist/vite/generate.js +2 -4
- package/dist/vite/generate.js.map +1 -1
- package/package.json +4 -4
|
@@ -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;AA0ED,wBAAgB,iBAAiB,CAAC,EAChC,OAAY,EACZ,MAAM,EACN,UAAU,EACV,gBAAgB,GACjB,EAAE,wBAAwB,GAAG,MAAM,
|
|
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,CAsHnC"}
|
package/dist/vite/generate.js
CHANGED
|
@@ -130,13 +130,11 @@ export function generateAppModule({ layouts = [], routes, navigation, settingsSe
|
|
|
130
130
|
// biome-ignore-all format: generated code has stable, reviewable output.
|
|
131
131
|
// biome-ignore-all assist/source/organizeImports: generated imports follow route order.
|
|
132
132
|
import {createRoute, createRouter} from '@tanstack/react-router';
|
|
133
|
-
import {
|
|
133
|
+
import {assertRouteImplFrame, buildAnchorSkeleton, parseAppSearch, stringifyAppSearch, type RouteImpl, type RouterContext} from '@shipfox/client-shell/runtime';
|
|
134
134
|
${imports}
|
|
135
135
|
|
|
136
136
|
function routeOptions<T extends RouteImpl>(routeImpl: T, impl: string, path: string): T['options'] {
|
|
137
|
-
|
|
138
|
-
throw new TypeError(\`Route implementation "\${impl}" for "\${path}" must export default defineRoute(...).\`);
|
|
139
|
-
}
|
|
137
|
+
assertRouteImplFrame(routeImpl, impl, path);
|
|
140
138
|
return routeImpl.options;
|
|
141
139
|
}
|
|
142
140
|
|
|
@@ -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 [\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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"}
|
|
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 {assertRouteImplFrame, buildAnchorSkeleton, 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 assertRouteImplFrame(routeImpl, impl, path);\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": "
|
|
4
|
+
"version": "21.0.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/ShipfoxHQ/shipfox.git",
|
|
@@ -41,9 +41,9 @@
|
|
|
41
41
|
"@shipfox/api-auth-dto": "12.0.0",
|
|
42
42
|
"@shipfox/api-workspaces-dto": "12.0.0",
|
|
43
43
|
"@shipfox/client-api": "6.0.1",
|
|
44
|
-
"@shipfox/client-config": "
|
|
45
|
-
"@shipfox/client-ui": "
|
|
46
|
-
"@shipfox/react-ui": "
|
|
44
|
+
"@shipfox/client-config": "21.0.0",
|
|
45
|
+
"@shipfox/client-ui": "21.0.0",
|
|
46
|
+
"@shipfox/react-ui": "2.0.0"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
49
|
"@storybook/react": "^10.4.6",
|