fastapi-voyager 0.15.1__tar.gz → 0.15.2__tar.gz

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 (83) hide show
  1. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/PKG-INFO +1 -1
  2. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/docs/changelog.md +4 -2
  3. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/version.py +1 -1
  4. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/web/index.html +38 -1
  5. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/web/store.js +2 -0
  6. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/web/vue-main.js +47 -10
  7. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/.githooks/README.md +0 -0
  8. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/.githooks/pre-commit +0 -0
  9. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  10. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  11. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/.github/workflows/publish.yml +0 -0
  12. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/.gitignore +0 -0
  13. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/.prettierignore +0 -0
  14. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/.prettierrc +0 -0
  15. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/.python-version +0 -0
  16. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/CONTRIBUTING.md +0 -0
  17. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/LICENSE +0 -0
  18. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/README.md +0 -0
  19. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/docs/claude/0_REFACTORING_RENDER_NOTES.md +0 -0
  20. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/docs/idea.md +0 -0
  21. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/package-lock.json +0 -0
  22. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/pyproject.toml +0 -0
  23. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/release.md +0 -0
  24. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/setup-hooks.sh +0 -0
  25. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/__init__.py +0 -0
  26. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/cli.py +0 -0
  27. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/er_diagram.py +0 -0
  28. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/filter.py +0 -0
  29. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/module.py +0 -0
  30. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/pydantic_resolve_util.py +0 -0
  31. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/render.py +0 -0
  32. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/render_style.py +0 -0
  33. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/server.py +0 -0
  34. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/templates/dot/cluster.j2 +0 -0
  35. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/templates/dot/cluster_container.j2 +0 -0
  36. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/templates/dot/digraph.j2 +0 -0
  37. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/templates/dot/er_diagram.j2 +0 -0
  38. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/templates/dot/link.j2 +0 -0
  39. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/templates/dot/route_node.j2 +0 -0
  40. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/templates/dot/schema_node.j2 +0 -0
  41. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/templates/dot/tag_node.j2 +0 -0
  42. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/templates/html/colored_text.j2 +0 -0
  43. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/templates/html/pydantic_meta.j2 +0 -0
  44. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/templates/html/schema_field_row.j2 +0 -0
  45. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/templates/html/schema_header.j2 +0 -0
  46. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/templates/html/schema_table.j2 +0 -0
  47. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/type.py +0 -0
  48. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/type_helper.py +0 -0
  49. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/voyager.py +0 -0
  50. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/web/component/demo.js +0 -0
  51. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/web/component/render-graph.js +0 -0
  52. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/web/component/route-code-display.js +0 -0
  53. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/web/component/schema-code-display.js +0 -0
  54. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/web/graph-ui.js +0 -0
  55. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/web/graphviz.svg.css +0 -0
  56. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/web/graphviz.svg.js +0 -0
  57. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/web/icon/android-chrome-192x192.png +0 -0
  58. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/web/icon/android-chrome-512x512.png +0 -0
  59. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/web/icon/apple-touch-icon.png +0 -0
  60. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/web/icon/favicon-16x16.png +0 -0
  61. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/web/icon/favicon-32x32.png +0 -0
  62. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/web/icon/favicon.ico +0 -0
  63. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/web/icon/site.webmanifest +0 -0
  64. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/web/quasar.min.css +0 -0
  65. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/src/fastapi_voyager/web/quasar.min.js +0 -0
  66. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/tests/__init__.py +0 -0
  67. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/tests/demo.py +0 -0
  68. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/tests/demo_anno.py +0 -0
  69. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/tests/programatic.py +0 -0
  70. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/tests/service/__init__.py +0 -0
  71. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/tests/service/schema/__init__.py +0 -0
  72. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/tests/service/schema/base_entity.py +0 -0
  73. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/tests/service/schema/extra.py +0 -0
  74. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/tests/service/schema/schema.py +0 -0
  75. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/tests/test_analysis.py +0 -0
  76. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/tests/test_filter.py +0 -0
  77. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/tests/test_generic.py +0 -0
  78. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/tests/test_import.py +0 -0
  79. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/tests/test_module.py +0 -0
  80. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/tests/test_resolve_util_impl.py +0 -0
  81. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/tests/test_type_helper.py +0 -0
  82. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/uv.lock +0 -0
  83. {fastapi_voyager-0.15.1 → fastapi_voyager-0.15.2}/voyager.jpg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi-voyager
3
- Version: 0.15.1
3
+ Version: 0.15.2
4
4
  Summary: Visualize FastAPI application's routing tree and dependencies
5
5
  Project-URL: Homepage, https://github.com/allmonday/fastapi-voyager
6
6
  Project-URL: Source, https://github.com/allmonday/fastapi-voyager
@@ -161,9 +161,11 @@
161
161
  - [x] refactor er diagram renderer
162
162
  - [x] fix error in search function
163
163
  - 0.15.2
164
- - [ ] add tests
165
- - [ ] left panel can be toggled.
164
+ - [x] fix resetSearch issue: fail to go back previous tag/router after reset.
165
+ - [x] left panel can be toggled.
166
+ - 0.15.3
166
167
  - [ ] refactor vue-main.js, move methods to store
168
+ - [ ] add tests
167
169
 
168
170
  ## 1.0, release
169
171
 
@@ -1,2 +1,2 @@
1
1
  __all__ = ["__version__"]
2
- __version__ = "0.15.1"
2
+ __version__ = "0.15.2"
@@ -101,6 +101,30 @@
101
101
  }
102
102
  }
103
103
 
104
+ /* Tag Navigator Collapse Button */
105
+ .tag-navigator-collapse-btn-right {
106
+ position: absolute;
107
+ bottom: 8px;
108
+ left: 8px;
109
+ width: 32px;
110
+ height: 32px;
111
+ border-radius: 50%;
112
+ background: #009485;
113
+ color: white;
114
+ border: 2px solid white;
115
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
116
+ cursor: pointer;
117
+ display: flex;
118
+ align-items: center;
119
+ justify-content: center;
120
+ z-index: 100;
121
+ transition: all 0.2s ease;
122
+ }
123
+ .tag-navigator-collapse-btn-right:hover {
124
+ background: #007a6d;
125
+ box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
126
+ }
127
+
104
128
  /* App boot loading overlay & gating */
105
129
  #app-loading-overlay {
106
130
  position: fixed;
@@ -352,7 +376,7 @@
352
376
  <q-splitter
353
377
  v-model="store.state.leftPanel.width"
354
378
  unit="px"
355
- :limits="store.state.mode === 'voyager' ? [200, 800] : [0, 0]"
379
+ :limits="store.state.mode === 'voyager' ? [0, 800] : [0, 0]"
356
380
  class="adjust-fit"
357
381
  >
358
382
  <template #before>
@@ -509,6 +533,19 @@
509
533
  />
510
534
  </div>
511
535
  </div>
536
+
537
+ <!-- Collapse toggle button for tag navigator - at bottom-left of right panel -->
538
+ <div
539
+ v-show="store.state.mode === 'voyager'"
540
+ class="tag-navigator-collapse-btn-right"
541
+ @click="toggleTagNavigatorCollapse"
542
+ :title="store.state.leftPanel.collapsed ? 'Expand tag navigator' : 'Collapse tag navigator'"
543
+ >
544
+ <q-icon
545
+ :name="store.state.leftPanel.collapsed ? 'chevron_right' : 'chevron_left'"
546
+ size="18px"
547
+ />
548
+ </div>
512
549
  </div>
513
550
  </template>
514
551
  </q-splitter>
@@ -41,9 +41,11 @@ const state = reactive({
41
41
  width: 300,
42
42
  previousWidth: 300,
43
43
  tags: null,
44
+ fullTagsCache: null, // Cache for full tags (before search)
44
45
  tag: null,
45
46
  _tag: null,
46
47
  routeId: null,
48
+ collapsed: false,
47
49
  },
48
50
 
49
51
  graph: {
@@ -42,9 +42,13 @@ const app = createApp({
42
42
  graphUI = new GraphUI("#graph", {
43
43
  onSchemaShiftClick: (id) => {
44
44
  if (store.state.graph.schemaKeys.has(id)) {
45
- store.state.previousTagRoute.tag = store.state.leftPanel.tag
46
- store.state.previousTagRoute.routeId = store.state.leftPanel.routeId
47
- store.state.previousTagRoute.hasValue = true
45
+ // Only save current tag/route if we're not already in search mode
46
+ // This prevents overwriting the saved state with null values
47
+ if (!store.state.previousTagRoute.hasValue && !store.state.search.mode) {
48
+ store.state.previousTagRoute.tag = store.state.leftPanel.tag
49
+ store.state.previousTagRoute.routeId = store.state.leftPanel.routeId
50
+ store.state.previousTagRoute.hasValue = true
51
+ }
48
52
  store.state.search.mode = true
49
53
  store.state.search.schemaName = id
50
54
  onSearch()
@@ -183,9 +187,9 @@ const app = createApp({
183
187
 
184
188
  async function resetSearch() {
185
189
  store.state.search.mode = false
186
- console.log(store.state.previousTagRoute.hasValue)
187
- console.log(store.state.previousTagRoute)
188
- if (store.state.previousTagRoute.hasValue) {
190
+ const hadPreviousValue = store.state.previousTagRoute.hasValue
191
+
192
+ if (hadPreviousValue) {
189
193
  store.state.leftPanel.tag = store.state.previousTagRoute.tag
190
194
  store.state.leftPanel._tag = store.state.previousTagRoute.tag
191
195
  store.state.leftPanel.routeId = store.state.previousTagRoute.routeId
@@ -197,12 +201,25 @@ const app = createApp({
197
201
  }
198
202
 
199
203
  syncSelectionToUrl()
200
- await loadSearchedTags()
201
- renderBasedOnInitialPolicy()
204
+
205
+ // Load the full tags from cache (not search results) since we're resetting search
206
+ loadFullTags()
207
+
208
+ // If we restored a previous tag/route, generate with it
209
+ // Otherwise, fall back to initial policy
210
+ if (hadPreviousValue) {
211
+ onGenerate()
212
+ } else {
213
+ renderBasedOnInitialPolicy()
214
+ }
215
+ }
216
+
217
+ function loadFullTags() {
218
+ // Restore from cache (set by loadInitial)
219
+ store.state.leftPanel.tags = store.state.leftPanel.fullTagsCache
202
220
  }
203
221
 
204
222
  async function onSearch() {
205
- console.log("start search")
206
223
  store.state.search.mode = true
207
224
  store.state.leftPanel.tag = null
208
225
  store.state.leftPanel._tag = null
@@ -241,7 +258,10 @@ const app = createApp({
241
258
  try {
242
259
  const res = await fetch("dot")
243
260
  const data = await res.json()
244
- store.state.leftPanel.tags = Array.isArray(data.tags) ? data.tags : []
261
+ const tags = Array.isArray(data.tags) ? data.tags : []
262
+ store.state.leftPanel.tags = tags
263
+ // Cache the full tags for later use (e.g., resetSearch)
264
+ store.state.leftPanel.fullTagsCache = tags
245
265
 
246
266
  const schemasArr = Array.isArray(data.schemas) ? data.schemas : []
247
267
  // Build dict keyed by id for faster lookups and simpler prop passing
@@ -430,6 +450,22 @@ const app = createApp({
430
450
  syncSelectionToUrl()
431
451
  }
432
452
 
453
+ function toggleTagNavigatorCollapse() {
454
+ if (store.state.leftPanel.collapsed) {
455
+ // Expand: restore previous width
456
+ const fallbackWidth = store.state.leftPanel.previousWidth || 300
457
+ store.state.leftPanel.width = fallbackWidth
458
+ store.state.leftPanel.collapsed = false
459
+ } else {
460
+ // Collapse: save current width and set to 0
461
+ if (store.state.leftPanel.width > 0) {
462
+ store.state.leftPanel.previousWidth = store.state.leftPanel.width
463
+ }
464
+ store.state.leftPanel.width = 0
465
+ store.state.leftPanel.collapsed = true
466
+ }
467
+ }
468
+
433
469
  function selectRoute(routeId) {
434
470
  // find belonging tag
435
471
  const belongingTag = findTagByRoute(routeId)
@@ -558,6 +594,7 @@ const app = createApp({
558
594
  filterSearchSchemas,
559
595
  onSearchSchemaChange,
560
596
  toggleTag,
597
+ toggleTagNavigatorCollapse,
561
598
  toggleBrief,
562
599
  toggleHidePrimitiveRoute,
563
600
  selectRoute,