@dfosco/storyboard-core 2.4.0 → 2.5.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dfosco/storyboard-core",
3
- "version": "2.4.0",
3
+ "version": "2.5.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "repository": {
package/src/viewfinder.js CHANGED
@@ -16,13 +16,17 @@ export function hash(str) {
16
16
  /**
17
17
  * Resolve the target route path for a flow.
18
18
  *
19
+ * Priority:
19
20
  * 1. If flow name matches a known route (case-insensitive), use that route
20
- * 2. If flow data has a top-level `route`, or `meta.route` / `sceneMeta.route`, use that
21
- * 3. Fall back to root "/"
21
+ * 2. If flow data has an explicit top-level `route`, or `meta.route` / `flowMeta.route`, use that
22
+ * 3. If flow data has `_route` (inferred from file path by Vite plugin), use that
23
+ * 4. Fall back to root "/"
24
+ *
25
+ * Flows with `meta.default: true` targeting a route omit the `?flow=` param.
22
26
  *
23
27
  * @param {string} flowName
24
28
  * @param {string[]} knownRoutes - Array of route names (e.g. ["Dashboard", "Repositories"])
25
- * @returns {string} Full path with ?flow= param
29
+ * @returns {string} Full path with optional ?flow= param
26
30
  */
27
31
  export function resolveFlowRoute(flowName, knownRoutes = []) {
28
32
  // Case-insensitive match against known routes
@@ -34,14 +38,22 @@ export function resolveFlowRoute(flowName, knownRoutes = []) {
34
38
  }
35
39
  }
36
40
 
37
- // Check for explicit route: top-level `route`, then meta.route, then legacy sceneMeta.route
38
41
  try {
39
42
  const data = loadFlow(flowName)
40
- const route = data?.route || data?.meta?.route || data?.flowMeta?.route || data?.sceneMeta?.route
41
- if (route) {
42
- const normalized = route.startsWith('/') ? route : `/${route}`
43
+
44
+ // Check for explicit route: top-level `route`, then meta.route, then legacy sceneMeta.route
45
+ const explicitRoute = data?.route || data?.meta?.route || data?.flowMeta?.route || data?.sceneMeta?.route
46
+ if (explicitRoute) {
47
+ const normalized = explicitRoute.startsWith('/') ? explicitRoute : `/${explicitRoute}`
48
+ if (data?.meta?.default === true) return normalized
43
49
  return `${normalized}?flow=${encodeURIComponent(flowName)}`
44
50
  }
51
+
52
+ // Use inferred route from file path (injected by Vite data plugin)
53
+ if (data?._route) {
54
+ if (data?.meta?.default === true) return data._route
55
+ return `${data._route}?flow=${encodeURIComponent(flowName)}`
56
+ }
45
57
  } catch {
46
58
  // ignore load errors
47
59
  }
@@ -12,6 +12,9 @@ const makeIndex = () => ({
12
12
  'meta-author': { flowMeta: { author: 'dfosco' }, title: 'With Author' },
13
13
  'meta-authors': { flowMeta: { author: ['dfosco', 'heyamie', 'branonconor'] }, title: 'Multi Author' },
14
14
  'meta-both': { flowMeta: { route: '/Overview', author: 'octocat' }, title: 'Both' },
15
+ 'inferred-route': { _route: '/Dashboard', title: 'Inferred' },
16
+ 'inferred-default': { _route: '/Settings', meta: { default: true }, title: 'Default Flow' },
17
+ 'explicit-wins': { route: '/Forms', _route: '/Dashboard', title: 'Explicit Wins' },
15
18
  },
16
19
  objects: {},
17
20
  records: {},
@@ -105,6 +108,31 @@ describe('resolveFlowRoute', () => {
105
108
  })
106
109
  expect(resolveFlowRoute('conflict', [])).toBe('/Forms?flow=conflict')
107
110
  })
111
+
112
+ it('uses _route when no explicit route exists', () => {
113
+ expect(resolveFlowRoute('inferred-route', routes)).toBe('/Dashboard?flow=inferred-route')
114
+ })
115
+
116
+ it('prefers explicit route over _route', () => {
117
+ expect(resolveFlowRoute('explicit-wins', routes)).toBe('/Forms?flow=explicit-wins')
118
+ })
119
+
120
+ it('omits ?flow= when meta.default is true (inferred route)', () => {
121
+ expect(resolveFlowRoute('inferred-default', routes)).toBe('/Settings')
122
+ })
123
+
124
+ it('omits ?flow= when meta.default is true (explicit route)', () => {
125
+ init({
126
+ flows: { 'default-explicit': { route: '/Overview', meta: { default: true } } },
127
+ objects: {},
128
+ records: {},
129
+ })
130
+ expect(resolveFlowRoute('default-explicit', [])).toBe('/Overview')
131
+ })
132
+
133
+ it('still appends ?flow= when meta.default is absent even with _route', () => {
134
+ expect(resolveFlowRoute('inferred-route', [])).toBe('/Dashboard?flow=inferred-route')
135
+ })
108
136
  })
109
137
 
110
138
  describe('getFlowMeta', () => {