fastapi-voyager 0.9.5__py3-none-any.whl → 0.10.1__py3-none-any.whl

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.
fastapi_voyager/render.py CHANGED
@@ -62,9 +62,8 @@ class Renderer:
62
62
  else:
63
63
  raise ValueError(f'Unknown link type: {link.type}')
64
64
 
65
- def render_module_schema_wrapper(self, mods: list[ModuleNode]) -> str:
65
+ def render_module_schema_content(self, mods: list[ModuleNode]) -> str:
66
66
  module_color_flag = set(self.module_color.keys())
67
- print(module_color_flag)
68
67
 
69
68
  def render_module_schema(mod: ModuleNode) -> str:
70
69
  color: Optional[str] = None
@@ -104,7 +103,7 @@ class Renderer:
104
103
  inner_nodes = [
105
104
  f'''
106
105
  "{r.id}" [
107
- label = " {r.name}: {r.response_schema} "
106
+ label = " {r.name} | {r.response_schema} "
108
107
  margin="0.5,0.1"
109
108
  shape = "record"
110
109
  ];''' for r in mod.routes
@@ -122,7 +121,7 @@ class Renderer:
122
121
  {child_str}
123
122
  }}'''
124
123
 
125
- def render_dot(self, tags: list[Tag], routes: list[Route], nodes: list[SchemaNode], links: list[Link]) -> str:
124
+ def render_dot(self, tags: list[Tag], routes: list[Route], nodes: list[SchemaNode], links: list[Link], spline_line=False) -> str:
126
125
  module_schemas = build_module_schema_tree(nodes)
127
126
  module_routes = build_module_route_tree(routes)
128
127
 
@@ -136,7 +135,7 @@ class Renderer:
136
135
  ])
137
136
 
138
137
 
139
- module_schemas_str = self.render_module_schema_wrapper(module_schemas)
138
+ module_schemas_str = self.render_module_schema_content(module_schemas)
140
139
  module_routes_str = '\n'.join(self.render_module_route(m) for m in module_routes)
141
140
  link_str = '\n'.join(self.render_link(link) for link in links)
142
141
 
@@ -144,6 +143,7 @@ class Renderer:
144
143
  digraph world {{
145
144
  pad="0.5"
146
145
  nodesep=0.8
146
+ {'splines=line' if spline_line else ''}
147
147
  fontname="Helvetica,Arial,sans-serif"
148
148
  node [fontname="Helvetica,Arial,sans-serif"]
149
149
  edge [
fastapi_voyager/server.py CHANGED
@@ -19,6 +19,7 @@ class OptionParam(BaseModel):
19
19
  tags: list[Tag]
20
20
  schemas: list[SchemaNode]
21
21
  dot: str
22
+ enable_brief_mode: bool
22
23
 
23
24
  class Payload(BaseModel):
24
25
  tags: Optional[list[str]] = None
@@ -53,11 +54,10 @@ def create_route(
53
54
  schemas = voyager.nodes[:]
54
55
  schemas.sort(key=lambda s: s.name)
55
56
 
56
- return OptionParam(tags=tags, schemas=schemas, dot=dot)
57
+ return OptionParam(tags=tags, schemas=schemas, dot=dot, enable_brief_mode=bool(module_prefix))
57
58
 
58
59
  @router.post("/dot", response_class=PlainTextResponse)
59
60
  def get_filtered_dot(payload: Payload) -> str:
60
- print(payload)
61
61
  voyager = Voyager(
62
62
  include_tags=payload.tags,
63
63
  schema=payload.schema_name,
@@ -1,2 +1,2 @@
1
1
  __all__ = ["__version__"]
2
- __version__ = "0.9.5"
2
+ __version__ = "0.10.1"
@@ -1,4 +1,4 @@
1
- import inspect
1
+ from pydantic import BaseModel
2
2
  from fastapi import FastAPI, routing
3
3
  from fastapi_voyager.type_helper import (
4
4
  get_core_types,
@@ -54,9 +54,14 @@ class Voyager:
54
54
 
55
55
  def _get_available_route(self, app: FastAPI):
56
56
  for route in app.routes:
57
- if isinstance(route, routing.APIRoute) and route.response_model:
57
+ if isinstance(route, routing.APIRoute):
58
58
  yield route
59
59
 
60
+ def analysis_route(self, route: routing.APIRoute):
61
+ ...
62
+
63
+ def analysis_tags(self, tag: str):
64
+ ...
60
65
 
61
66
  def analysis(self, app: FastAPI):
62
67
  """
@@ -68,67 +73,76 @@ class Voyager:
68
73
  """
69
74
  schemas: list[type[BaseModel]] = []
70
75
 
76
+ # First, group all routes by tag
77
+ routes_by_tag: dict[str, list] = {}
71
78
  for route in self._get_available_route(app):
72
- # check tags
73
79
  tags = getattr(route, 'tags', None)
74
- route_tag = tags[0] if tags else '__default__'
75
- if self.include_tags and route_tag not in self.include_tags:
76
- continue
77
80
 
78
- # add tag if not exists
79
- tag_id = f'tag__{route_tag}'
80
- if tag_id not in self.tag_set:
81
- tag_obj = Tag(id=tag_id, name=route_tag, routes=[])
82
- self.tag_set[tag_id] = tag_obj
83
- self.tags.append(tag_obj)
84
-
85
- # add route and create links
86
- route_id = full_class_name(route.endpoint)
87
- route_name = route.endpoint.__name__
88
- route_module = route.endpoint.__module__
89
-
90
- # filter by route_name (route.id) if provided
91
- if self.route_name is not None and route_id != self.route_name:
92
- continue
81
+ # using multiple tags is harmful, it's not recommended and will not be supported
82
+ route_tag = tags[0] if tags else '__default__'
83
+ routes_by_tag.setdefault(route_tag, []).append(route)
93
84
 
94
- is_primitive_response = is_non_pydantic_type(route.response_model)
95
- # filter primitive route if needed
96
- if self.hide_primitive_route and is_primitive_response:
97
- continue
85
+ # Then filter by include_tags if provided
86
+ if self.include_tags:
87
+ filtered_routes_by_tag = {tag: routes for tag, routes in routes_by_tag.items()
88
+ if tag in self.include_tags}
89
+ else:
90
+ filtered_routes_by_tag = routes_by_tag
98
91
 
99
- self.links.append(Link(
100
- source=tag_id,
101
- source_origin=tag_id,
102
- target=route_id,
103
- target_origin=route_id,
104
- type='tag_route'
105
- ))
92
+ # Process filtered routes
93
+ for route_tag, routes in filtered_routes_by_tag.items():
106
94
 
107
- route_obj = Route(
108
- id=route_id,
109
- name=route_name,
110
- module=route_module,
111
- response_schema=get_type_name(route.response_model),
112
- is_primitive=is_primitive_response
113
- )
114
- self.routes.append(route_obj)
115
- # add route into current tag
116
- self.tag_set[tag_id].routes.append(route_obj)
117
-
118
- # add response_models and create links from route -> response_model
119
- for schema in get_core_types(route.response_model):
120
- if schema and issubclass(schema, BaseModel):
121
- is_primitive_response = False
122
- target_name = full_class_name(schema)
123
- self.links.append(Link(
124
- source=route_id,
125
- source_origin=route_id,
126
- target=self.generate_node_head(target_name),
127
- target_origin=target_name,
128
- type='route_to_schema'
129
- ))
130
-
131
- schemas.append(schema)
95
+ tag_id = f'tag__{route_tag}'
96
+ tag_obj = Tag(id=tag_id, name=route_tag, routes=[])
97
+ self.tags.append(tag_obj)
98
+
99
+ for route in routes:
100
+ # add route and create links
101
+ route_id = full_class_name(route.endpoint)
102
+ route_name = route.endpoint.__name__
103
+ route_module = route.endpoint.__module__
104
+
105
+ # filter by route_name (route.id) if provided
106
+ if self.route_name is not None and route_id != self.route_name:
107
+ continue
108
+
109
+ is_primitive_response = is_non_pydantic_type(route.response_model)
110
+ # filter primitive route if needed
111
+ if self.hide_primitive_route and is_primitive_response:
112
+ continue
113
+
114
+ self.links.append(Link(
115
+ source=tag_id,
116
+ source_origin=tag_id,
117
+ target=route_id,
118
+ target_origin=route_id,
119
+ type='tag_route'
120
+ ))
121
+
122
+ route_obj = Route(
123
+ id=route_id,
124
+ name=route_name,
125
+ module=route_module,
126
+ response_schema=get_type_name(route.response_model),
127
+ is_primitive=is_primitive_response
128
+ )
129
+ self.routes.append(route_obj)
130
+ tag_obj.routes.append(route_obj)
131
+
132
+ # add response_models and create links from route -> response_model
133
+ for schema in get_core_types(route.response_model):
134
+ if schema and issubclass(schema, BaseModel):
135
+ is_primitive_response = False
136
+ target_name = full_class_name(schema)
137
+ self.links.append(Link(
138
+ source=route_id,
139
+ source_origin=route_id,
140
+ target=self.generate_node_head(target_name),
141
+ target_origin=target_name,
142
+ type='route_to_schema'
143
+ ))
144
+
145
+ schemas.append(schema)
132
146
 
133
147
  for s in schemas:
134
148
  self.analysis_schemas(s)
@@ -271,6 +285,12 @@ class Voyager:
271
285
  schema=self.schema
272
286
  )
273
287
 
288
+ def handle_hide(self, tags, routes, links):
289
+ if self.include_tags:
290
+ return [], routes, [lk for lk in links if lk.type != 'tag_route']
291
+ else:
292
+ return tags, routes, links
293
+
274
294
  def render_dot(self):
275
295
  _tags, _routes, _nodes, _links = filter_graph(
276
296
  schema=self.schema,
@@ -281,7 +301,10 @@ class Voyager:
281
301
  links=self.links,
282
302
  node_set=self.node_set,
283
303
  )
304
+
284
305
  renderer = Renderer(show_fields=self.show_fields, module_color=self.module_color, schema=self.schema)
306
+
307
+ _tags, _routes, _links = self.handle_hide(_tags, _routes, _links)
285
308
  return renderer.render_dot(_tags, _routes, _nodes, _links)
286
309
 
287
310
  def render_brief_dot(self, module_prefix: str | None = None):
@@ -293,4 +316,6 @@ class Voyager:
293
316
  links=self.links,
294
317
  )
295
318
  renderer = Renderer(show_fields=self.show_fields, module_color=self.module_color, schema=None)
296
- return renderer.render_dot(_tags, _routes, _nodes, _links)
319
+
320
+ _tags, _routes, _links = self.handle_hide(_tags, _routes, _links)
321
+ return renderer.render_dot(_tags, _routes, _nodes, _links, True)
@@ -86,6 +86,7 @@
86
86
  </div>
87
87
  <div class="col-auto q-ml-auto">
88
88
  <q-toggle
89
+ v-if="state.enableBriefMode"
89
90
  class="q-mr-md"
90
91
  v-model="state.brief"
91
92
  label="Brief Mode"
@@ -163,12 +164,29 @@
163
164
 
164
165
  <q-drawer
165
166
  v-model="state.detailDrawer"
166
- width="500"
167
+ :width="state.drawerWidth"
167
168
  side="right"
169
+ style="border-left: 1px solid #888;"
168
170
  overlay
169
171
  bordered
170
172
  >
171
- <div style="z-index: 1; position: absolute; left: -17px; top: 9px">
173
+ <!-- 可拖拽的调整栏 -->
174
+ <div
175
+ @mousedown="startDragDrawer"
176
+ style="
177
+ position: absolute;
178
+ left: -3px;
179
+ top: 0;
180
+ width: 6px;
181
+ height: 100%;
182
+ cursor: col-resize;
183
+ background: transparent;
184
+ z-index: 10;
185
+ "
186
+ title="drag to resize"
187
+ ></div>
188
+
189
+ <div style="z-index: 11; position: absolute; left: -17px; top: 9px">
172
190
  <q-btn
173
191
  @click="state.detailDrawer = !state.detailDrawer"
174
192
  round
@@ -208,14 +226,14 @@
208
226
  v-for="tag in state.rawTags"
209
227
  :key="tag.name"
210
228
  expand-separator
211
- :model-value="state.tag === tag.name"
229
+ :model-value="state._tag === tag.name"
212
230
  @update:model-value="(val) => toggleTag(tag.name, val)"
213
231
  :header-class="state.tag === tag.name ? 'text-primary text-bold' : ''"
214
232
  content-class="q-pa-none"
215
233
  >
216
234
  <template #header>
217
235
  <div class="row items-center" style="width: 100%">
218
- <div class="row items-end">
236
+ <div class="row items-center">
219
237
  <q-icon
220
238
  class="q-mr-sm"
221
239
  :name="state.tag == tag.name ? 'folder' : 'folder_open'"
@@ -260,7 +278,17 @@
260
278
  </template>
261
279
 
262
280
  <template #after>
263
- <div id="graph" class="fit"></div>
281
+ <div style="position: relative; width: 100%; height: 100%;">
282
+ <div id="graph" class="fit"></div>
283
+ <q-toggle
284
+ v-model="state.focus"
285
+ v-show="schemaCodeName"
286
+ @update:model-value="val => onFocusChange(val)"
287
+ label="Focus"
288
+ style="position: absolute; left: 8px; top: 8px; z-index: 10; background: rgba(255,255,255,0.85); border-radius: 4px; padding: 2px 8px;"
289
+ size="sm"
290
+ />
291
+ </div>
264
292
  </template>
265
293
  </q-splitter>
266
294
  </q-page-container>
@@ -10,6 +10,7 @@ const app = createApp({
10
10
  const state = reactive({
11
11
  // options and selections
12
12
  tag: null, // picked tag
13
+ _tag: null, // display tag
13
14
  routeId: null, // picked route
14
15
  schemaId: null, // picked schema
15
16
  showFields: "object",
@@ -18,7 +19,9 @@ const app = createApp({
18
19
  { label: "Object fields", value: "object" },
19
20
  { label: "All fields", value: "all" },
20
21
  ],
22
+ enableBriefMode: false,
21
23
  brief: false,
24
+ focus: false,
22
25
  hidePrimitiveRoute: false,
23
26
  generating: false,
24
27
  rawTags: [], // [{ name, routes: [{ id, name }] }]
@@ -28,6 +31,7 @@ const app = createApp({
28
31
  // Splitter size (left panel width in px)
29
32
  splitter: 300,
30
33
  detailDrawer: false,
34
+ drawerWidth: 500, // drawer 宽度
31
35
  });
32
36
 
33
37
  const showDetail = ref(false);
@@ -70,6 +74,7 @@ const app = createApp({
70
74
  acc[r.id] = r;
71
75
  return acc;
72
76
  }, {});
77
+ state.enableBriefMode = data.enable_brief_mode || false;
73
78
 
74
79
  // default route options placeholder
75
80
  } catch (e) {
@@ -79,18 +84,30 @@ const app = createApp({
79
84
  }
80
85
  }
81
86
 
82
- async function onGenerate(resetZoom = true) {
87
+ async function onFocusChange(val) {
88
+ if (val) {
89
+ await onGenerate(false, schemaCodeName.value)
90
+ } else {
91
+ await onGenerate(false, null)
92
+ setTimeout(() => {
93
+ const ele = $(`[data-name='${schemaCodeName.value}'] polygon`)
94
+ debugger
95
+ ele.click()
96
+ }, 1)
97
+ }
98
+ }
99
+
100
+ async function onGenerate(resetZoom = true, schema_name = null) {
83
101
  state.generating = true;
84
102
  try {
85
103
  const payload = {
86
104
  tags: state.tag ? [state.tag] : null,
87
- schema_name: state.schemaId || null,
105
+ schema_name: schema_name || null,
88
106
  route_name: state.routeId || null,
89
107
  show_fields: state.showFields,
90
108
  brief: state.brief,
91
109
  hide_primitive_route: state.hidePrimitiveRoute,
92
110
  };
93
-
94
111
  const res = await fetch("dot", {
95
112
  method: "POST",
96
113
  headers: { "Content-Type": "application/json" },
@@ -119,6 +136,7 @@ const app = createApp({
119
136
  resetCb: () => {
120
137
  state.detailDrawer = false;
121
138
  showRouteDetail.value = false;
139
+ schemaCodeName.value = ''
122
140
  }
123
141
  });
124
142
 
@@ -198,15 +216,23 @@ const app = createApp({
198
216
  state.schemaId = null;
199
217
  // state.showFields = "object";
200
218
  state.brief = false;
219
+ state.focus = false
220
+ schemaCodeName.value = ''
201
221
  onGenerate();
202
222
  }
203
223
 
204
224
  function toggleTag(tagName, expanded = null) {
205
225
  if (expanded === true) {
226
+ state._tag = tagName;
206
227
  state.tag = tagName;
207
228
  state.routeId = "";
229
+ state.focus = false
230
+ schemaCodeName.value = ''
208
231
  onGenerate();
232
+ } else {
233
+ state._tag = null
209
234
  }
235
+
210
236
  state.detailDrawer = false;
211
237
  showRouteDetail.value = false;
212
238
  }
@@ -219,6 +245,8 @@ const app = createApp({
219
245
  }
220
246
  state.detailDrawer = false;
221
247
  showRouteDetail.value = false;
248
+ state.focus = false
249
+ schemaCodeName.value = ''
222
250
  onGenerate();
223
251
  }
224
252
 
@@ -237,6 +265,30 @@ const app = createApp({
237
265
  onGenerate(false);
238
266
  }
239
267
 
268
+ function startDragDrawer(e) {
269
+ const startX = e.clientX;
270
+ const startWidth = state.drawerWidth;
271
+
272
+ function onMouseMove(moveEvent) {
273
+ const deltaX = startX - moveEvent.clientX;
274
+ const newWidth = Math.max(300, Math.min(800, startWidth + deltaX));
275
+ state.drawerWidth = newWidth;
276
+ }
277
+
278
+ function onMouseUp() {
279
+ document.removeEventListener('mousemove', onMouseMove);
280
+ document.removeEventListener('mouseup', onMouseUp);
281
+ document.body.style.cursor = '';
282
+ document.body.style.userSelect = '';
283
+ }
284
+
285
+ document.addEventListener('mousemove', onMouseMove);
286
+ document.addEventListener('mouseup', onMouseUp);
287
+ document.body.style.cursor = 'col-resize';
288
+ document.body.style.userSelect = 'none';
289
+ e.preventDefault();
290
+ }
291
+
240
292
  onMounted(async () => {
241
293
  await loadInitial();
242
294
  });
@@ -272,6 +324,8 @@ const app = createApp({
272
324
  showRenderGraph,
273
325
  renderCoreData,
274
326
  toggleShowField,
327
+ startDragDrawer,
328
+ onFocusChange
275
329
  };
276
330
  },
277
331
  });
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi-voyager
3
- Version: 0.9.5
3
+ Version: 0.10.1
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
@@ -167,14 +167,15 @@ or you can open router_viz.dot with vscode extension `graphviz interactive previ
167
167
  - [ ] add extra info for schema
168
168
  - [ ] display standard ER diagram `hard`
169
169
  - [ ] display potential invalid links
170
- - [ ] support dataclass (pending)
170
+ - [ ] optimize static resource (allow manually config url)
171
+ - [ ] improve search dialog
172
+ - [ ] add route/tag list
171
173
 
172
174
  ### in analysis
173
175
  - [ ] click field to highlight links
174
176
  - [ ] animation effect for edges
175
177
  - [ ] customrized right click panel
176
178
  - [ ] show own dependencies
177
- - [ ] clean up fe code
178
179
 
179
180
  ### plan:
180
181
  #### <0.9:
@@ -225,23 +226,20 @@ or you can open router_viz.dot with vscode extension `graphviz interactive previ
225
226
  - [x] route list should have a max height
226
227
 
227
228
  #### 0.10
228
- - [ ] perfomance: cache the origin data, refactor voyager.py
229
- - [ ] better edge for brief mode
229
+ - [x] refactor voyager.py tag -> route structure
230
+ - [x] fix missing route (tag has only one route which return primitive value)
231
+ - [x] make right panel resizable by dragging
232
+ - [x] allow closing tag expansion item
233
+ - [x] hide brief mode if not configured
234
+ - [x] add focus button to only show related nodes under current route/tag graph in dialog
235
+
236
+ #### 0.11
237
+ - [ ] enable/disable module cluster (to save space)
238
+ - [ ] fix layout issue when rendering huge graph
239
+ - [ ] logging information
230
240
  - [ ] support opening route in swagger
231
241
  - config docs path
232
- - [ ] add http method for route
233
- - [ ] enable/disable module cluster (may save space)
234
- - [ ] logging information
235
242
  - [ ] add tests
236
- - [ ] hide brief mode if not configured
237
- - [ ] optimize static resource (allow manually config url)
238
- - [ ] show route count in tag expansion item
239
- - [ ] route list should have a max height to trigger scrollable
240
- - [ ] fix layout issue when rendering huge graph
241
- - [ ] fix missing route (tag has only one route which return primitive value)
242
-
243
- #### 0.11
244
- - [ ] improve search dialog
245
243
 
246
244
  #### 0.12
247
245
  - [ ] integration with pydantic-resolve
@@ -251,6 +249,7 @@ or you can open router_viz.dot with vscode extension `graphviz interactive previ
251
249
  #### 0.13
252
250
  - [ ] config release pipeline
253
251
 
252
+
254
253
  ## Using with pydantic-resolve
255
254
 
256
255
  WIP: ...
@@ -2,19 +2,19 @@ fastapi_voyager/__init__.py,sha256=tZy0Nkj8kTaMgbvHy-mGxVcFGVX0Km-36dnzsAIG2uk,2
2
2
  fastapi_voyager/cli.py,sha256=kQb4g6JEGZR99e5r8LyFFEeb_-uT-n_gp_sDoYG3R7k,11118
3
3
  fastapi_voyager/filter.py,sha256=2Yt37o8mhqSqleafO4YRrumh_ExYUqzXFOxQRPuTbAc,8078
4
4
  fastapi_voyager/module.py,sha256=Z2QHNmiLk6ZAJlm2nSmO875Q33TweSg8UxZSzIpU9zY,3499
5
- fastapi_voyager/render.py,sha256=qy3g1Rz1s8XkuR_6n1Q1YPwy_oMOjWjNswTHQjdz4N0,7765
6
- fastapi_voyager/server.py,sha256=pg-LHDj4yU0usDA1b2X2Kt2_OCrexFA2G9ifGxb52Uc,6196
5
+ fastapi_voyager/render.py,sha256=sR1oUh8d3hhDalQhUcrL-k2ZYAWbLDGpGDOB0dDaqRQ,7804
6
+ fastapi_voyager/server.py,sha256=fyAfb6GwghcYBjk-pFJzj-uikUnATd7zmbYjUDN7bC8,6243
7
7
  fastapi_voyager/type.py,sha256=pWYKmgb9e0W_JeD7k54Mr2lxUZV_Ir9TNpewGRwHyHQ,1629
8
8
  fastapi_voyager/type_helper.py,sha256=hjBC4E0tgBpQDlYxGg74uK07SXjsrAgictEETJfIpYM,9231
9
- fastapi_voyager/version.py,sha256=edeIqVARN2rX8n02TnXhblafTm15NsTYlNCYyC9fXBo,48
10
- fastapi_voyager/voyager.py,sha256=QKWletUwZeHm8e8ZRcGm6OuhAdiik3tT7sOU-QnEuGA,11036
9
+ fastapi_voyager/version.py,sha256=cVQTkkihEPlsOisGI50rjHoCoQDT4b7cLPCnW6yGjYQ,49
10
+ fastapi_voyager/voyager.py,sha256=DIc93SFPVwrsk1Nga74ZZyc4L0J50OAESE9j3fnEty0,12053
11
11
  fastapi_voyager/web/graph-ui.js,sha256=FmKA3eeHMEeUDNuay3f54_fv4eGHT7MT0TaGqXhyMWQ,4978
12
12
  fastapi_voyager/web/graphviz.svg.css,sha256=zDCjjpT0Idufu5YOiZI76PL70-avP3vTyzGPh9M85Do,1563
13
13
  fastapi_voyager/web/graphviz.svg.js,sha256=lvAdbjHc-lMSk4GQp-iqYA2PCFX4RKnW7dFaoe0LUHs,16005
14
- fastapi_voyager/web/index.html,sha256=qH7vs_1SpFJWZlzMsPBuHToCysLpRsb4LC5vRBjWhZM,13930
14
+ fastapi_voyager/web/index.html,sha256=CCodl9CaxjWrdQG7y9qJlSe23G7LYwK7JvIHKVPV95E,14985
15
15
  fastapi_voyager/web/quasar.min.css,sha256=F5jQe7X2XT54VlvAaa2V3GsBFdVD-vxDZeaPLf6U9CU,203145
16
16
  fastapi_voyager/web/quasar.min.js,sha256=h0ftyPMW_CRiyzeVfQqiup0vrVt4_QWojpqmpnpn07E,502974
17
- fastapi_voyager/web/vue-main.js,sha256=bn4Q9FqX5RJVG9bA5xgUUt5TJf9CjiXcKtn_ikLsaKQ,8357
17
+ fastapi_voyager/web/vue-main.js,sha256=lM7bxq2ivnEH-zpHF6_U8d_ebsZSg-UbSiiktss5hd8,10062
18
18
  fastapi_voyager/web/component/render-graph.js,sha256=e8Xgh2Kl-nYU0P1gstEmAepCgFnk2J6UdxW8TlMafGs,2322
19
19
  fastapi_voyager/web/component/route-code-display.js,sha256=8NJPPjNRUC21gjpY8XYEQs4RBbhX1pCiqEhJp39ku6k,3678
20
20
  fastapi_voyager/web/component/schema-code-display.js,sha256=UgFotzvqSuhnPXNOr6w_r1fV2_savRiCdokEvferutE,6244
@@ -26,8 +26,8 @@ fastapi_voyager/web/icon/favicon-16x16.png,sha256=JC07jEzfIYxBIoQn_FHXvyHuxESdhW
26
26
  fastapi_voyager/web/icon/favicon-32x32.png,sha256=C7v1h58cfWOsiLp9yOIZtlx-dLasBcq3NqpHVGRmpt4,1859
27
27
  fastapi_voyager/web/icon/favicon.ico,sha256=tZolYIXkkBcFiYl1A8ksaXN2VjGamzcSdes838dLvNc,15406
28
28
  fastapi_voyager/web/icon/site.webmanifest,sha256=ep4Hzh9zhmiZF2At3Fp1dQrYQuYF_3ZPZxc1KcGBvwQ,263
29
- fastapi_voyager-0.9.5.dist-info/METADATA,sha256=fnFPewv9pgh6hA4k1SXufzEmq7a-2vmMwAvCl49xdQk,8833
30
- fastapi_voyager-0.9.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
31
- fastapi_voyager-0.9.5.dist-info/entry_points.txt,sha256=pEIKoUnIDXEtdMBq8EmXm70m16vELIu1VPz9-TBUFWM,53
32
- fastapi_voyager-0.9.5.dist-info/licenses/LICENSE,sha256=lNVRR3y_bFVoFKuK2JM8N4sFaj3m-7j29kvL3olFi5Y,1067
33
- fastapi_voyager-0.9.5.dist-info/RECORD,,
29
+ fastapi_voyager-0.10.1.dist-info/METADATA,sha256=RseoOEkS3k3BCnVZzQoGXj_kJVZNPGH7oCT2HuG9vyY,8794
30
+ fastapi_voyager-0.10.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
31
+ fastapi_voyager-0.10.1.dist-info/entry_points.txt,sha256=pEIKoUnIDXEtdMBq8EmXm70m16vELIu1VPz9-TBUFWM,53
32
+ fastapi_voyager-0.10.1.dist-info/licenses/LICENSE,sha256=lNVRR3y_bFVoFKuK2JM8N4sFaj3m-7j29kvL3olFi5Y,1067
33
+ fastapi_voyager-0.10.1.dist-info/RECORD,,