@dfosco/storyboard-core 1.6.0 → 1.7.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 +1 -1
- package/src/index.js +1 -1
- package/src/viewfinder.js +21 -5
- package/src/viewfinder.test.js +39 -1
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -32,7 +32,7 @@ export { mountDevTools } from './devtools.js'
|
|
|
32
32
|
export { mountSceneDebug } from './sceneDebug.js'
|
|
33
33
|
|
|
34
34
|
// Viewfinder utilities
|
|
35
|
-
export { hash, resolveSceneRoute } from './viewfinder.js'
|
|
35
|
+
export { hash, resolveSceneRoute, getSceneMeta } from './viewfinder.js'
|
|
36
36
|
|
|
37
37
|
// Comments system
|
|
38
38
|
export { initCommentsConfig, getCommentsConfig, isCommentsEnabled } from './comments/config.js'
|
package/src/viewfinder.js
CHANGED
|
@@ -17,7 +17,7 @@ export function hash(str) {
|
|
|
17
17
|
* Resolve the target route path for a scene.
|
|
18
18
|
*
|
|
19
19
|
* 1. If scene name matches a known route (case-insensitive), use that route
|
|
20
|
-
* 2. If scene data has a `route` key, use that
|
|
20
|
+
* 2. If scene data has a `sceneMeta.route` or `route` key, use that
|
|
21
21
|
* 3. Fall back to root "/"
|
|
22
22
|
*
|
|
23
23
|
* @param {string} sceneName
|
|
@@ -32,12 +32,13 @@ export function resolveSceneRoute(sceneName, knownRoutes = []) {
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
// Check for explicit
|
|
35
|
+
// Check for explicit route in sceneMeta or top-level route key
|
|
36
36
|
try {
|
|
37
37
|
const data = loadScene(sceneName)
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
const route = data?.sceneMeta?.route || data?.route
|
|
39
|
+
if (route) {
|
|
40
|
+
const normalized = route.startsWith('/') ? route : `/${route}`
|
|
41
|
+
return `${normalized}?scene=${encodeURIComponent(sceneName)}`
|
|
41
42
|
}
|
|
42
43
|
} catch {
|
|
43
44
|
// ignore load errors
|
|
@@ -45,3 +46,18 @@ export function resolveSceneRoute(sceneName, knownRoutes = []) {
|
|
|
45
46
|
|
|
46
47
|
return `/?scene=${encodeURIComponent(sceneName)}`
|
|
47
48
|
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Get sceneMeta for a scene (route, author, etc).
|
|
52
|
+
*
|
|
53
|
+
* @param {string} sceneName
|
|
54
|
+
* @returns {{ route?: string, author?: string } | null}
|
|
55
|
+
*/
|
|
56
|
+
export function getSceneMeta(sceneName) {
|
|
57
|
+
try {
|
|
58
|
+
const data = loadScene(sceneName)
|
|
59
|
+
return data?.sceneMeta || null
|
|
60
|
+
} catch {
|
|
61
|
+
return null
|
|
62
|
+
}
|
|
63
|
+
}
|
package/src/viewfinder.test.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { init } from './loader.js'
|
|
2
|
-
import { hash, resolveSceneRoute } from './viewfinder.js'
|
|
2
|
+
import { hash, resolveSceneRoute, getSceneMeta } from './viewfinder.js'
|
|
3
3
|
|
|
4
4
|
const makeIndex = () => ({
|
|
5
5
|
scenes: {
|
|
@@ -8,6 +8,9 @@ const makeIndex = () => ({
|
|
|
8
8
|
'custom-route': { route: 'Overview', title: 'Custom' },
|
|
9
9
|
'absolute-route': { route: '/Forms', title: 'Absolute' },
|
|
10
10
|
'no-route': { title: 'No route key' },
|
|
11
|
+
'meta-route': { sceneMeta: { route: 'Repositories' }, title: 'Meta Route' },
|
|
12
|
+
'meta-author': { sceneMeta: { author: 'dfosco' }, title: 'With Author' },
|
|
13
|
+
'meta-both': { sceneMeta: { route: '/Overview', author: 'octocat' }, title: 'Both' },
|
|
11
14
|
},
|
|
12
15
|
objects: {},
|
|
13
16
|
records: {},
|
|
@@ -84,4 +87,39 @@ describe('resolveSceneRoute', () => {
|
|
|
84
87
|
})
|
|
85
88
|
expect(resolveSceneRoute('has spaces', [])).toBe('/?scene=has%20spaces')
|
|
86
89
|
})
|
|
90
|
+
|
|
91
|
+
it('uses sceneMeta.route when no route matches', () => {
|
|
92
|
+
expect(resolveSceneRoute('meta-route', routes)).toBe('/Repositories?scene=meta-route')
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
it('uses sceneMeta.route with absolute path', () => {
|
|
96
|
+
expect(resolveSceneRoute('meta-both', routes)).toBe('/Overview?scene=meta-both')
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
it('prefers sceneMeta.route over top-level route key', () => {
|
|
100
|
+
init({
|
|
101
|
+
scenes: { conflict: { route: 'Forms', sceneMeta: { route: 'Dashboard' } } },
|
|
102
|
+
objects: {},
|
|
103
|
+
records: {},
|
|
104
|
+
})
|
|
105
|
+
expect(resolveSceneRoute('conflict', [])).toBe('/Dashboard?scene=conflict')
|
|
106
|
+
})
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
describe('getSceneMeta', () => {
|
|
110
|
+
it('returns sceneMeta when present', () => {
|
|
111
|
+
expect(getSceneMeta('meta-author')).toEqual({ author: 'dfosco' })
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
it('returns sceneMeta with both fields', () => {
|
|
115
|
+
expect(getSceneMeta('meta-both')).toEqual({ route: '/Overview', author: 'octocat' })
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
it('returns null when no sceneMeta', () => {
|
|
119
|
+
expect(getSceneMeta('default')).toBeNull()
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
it('returns null for nonexistent scene', () => {
|
|
123
|
+
expect(getSceneMeta('nonexistent')).toBeNull()
|
|
124
|
+
})
|
|
87
125
|
})
|