quickdbd-cli 0.4.2__tar.gz → 0.5.0__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 (259) hide show
  1. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/.gitignore +3 -0
  2. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/PKG-INFO +2 -2
  3. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/README.md +1 -1
  4. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/pyproject.toml +1 -1
  5. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/scripts/gen_thumbnails.py +1 -1
  6. quickdbd_cli-0.5.0/src/quickdbd_cli/__init__.py +1 -0
  7. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/assets/icon.svg +1 -1
  8. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/assets/style.css +2 -2
  9. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/cli.py +83 -5
  10. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/html.py +25 -0
  11. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/test_pipeline.py +49 -0
  12. quickdbd_cli-0.4.2/src/quickdbd_cli/__init__.py +0 -1
  13. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/LICENSE +0 -0
  14. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/NOTICE +0 -0
  15. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/examples/quickdbd-sample.txt +0 -0
  16. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/examples/synthetic/finance.txt +0 -0
  17. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/examples/synthetic/hr.txt +0 -0
  18. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/examples/synthetic/inventory.txt +0 -0
  19. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/examples/synthetic/marketing.txt +0 -0
  20. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/examples/synthetic/qdbd.layout.json +0 -0
  21. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/examples/synthetic/sales.txt +0 -0
  22. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/scripts/build_gallery.py +0 -0
  23. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/scripts/gen_font_metrics.py +0 -0
  24. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/scripts/gen_schema.py +0 -0
  25. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/scripts/import_dbml_corpus.py +0 -0
  26. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/scripts/release.sh +0 -0
  27. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/__main__.py +0 -0
  28. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/agent.py +0 -0
  29. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/assets/Inter-Bold.ttf +0 -0
  30. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/assets/Inter-Bold.woff2 +0 -0
  31. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/assets/Inter-LICENSE.txt +0 -0
  32. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/assets/Inter-Regular.ttf +0 -0
  33. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/assets/Inter-Regular.woff2 +0 -0
  34. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/assets/editor.js +0 -0
  35. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/assets/elk-LICENSE.md +0 -0
  36. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/assets/elk.bundled.js +0 -0
  37. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/assets/font-metrics.json +0 -0
  38. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/assets/render.js +0 -0
  39. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/assets/syntax-reference.md +0 -0
  40. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/assets/viewer.js +0 -0
  41. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/convert.py +0 -0
  42. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/dbml.py +0 -0
  43. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/dbt.py +0 -0
  44. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/diff.py +0 -0
  45. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/export.py +0 -0
  46. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/jsrt.py +0 -0
  47. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/layout.py +0 -0
  48. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/mcp.py +0 -0
  49. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/measure.py +0 -0
  50. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/model.py +0 -0
  51. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/parser.py +0 -0
  52. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/project.py +0 -0
  53. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/serve.py +0 -0
  54. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/share.py +0 -0
  55. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/tags.py +0 -0
  56. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/src/quickdbd_cli/targets.py +0 -0
  57. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml/team.dbml +0 -0
  58. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/LICENSE +0 -0
  59. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/README.md +0 -0
  60. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/alias_of_duplicated_names.dbml +0 -0
  61. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/alias_of_duplicated_names.json +0 -0
  62. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/dep.dbml +0 -0
  63. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/dep.json +0 -0
  64. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/duplicate_columns.dbml +0 -0
  65. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/duplicate_columns.json +0 -0
  66. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/duplicate_enum_field.dbml +0 -0
  67. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/duplicate_enum_field.json +0 -0
  68. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/duplicate_name.dbml +0 -0
  69. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/duplicate_name.json +0 -0
  70. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/duplicate_names.dbml +0 -0
  71. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/duplicate_names.json +0 -0
  72. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/duplicate_table_partial_injections.dbml +0 -0
  73. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/duplicate_table_partial_injections.json +0 -0
  74. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/enum_as_default_column_value.dbml +0 -0
  75. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/enum_as_default_column_value.json +0 -0
  76. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/enum_name.dbml +0 -0
  77. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/enum_name.json +0 -0
  78. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/erroneous.dbml +0 -0
  79. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/erroneous.json +0 -0
  80. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/multiple_notes_in_table_group.dbml +0 -0
  81. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/multiple_notes_in_table_group.json +0 -0
  82. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/nonexisting_column_in_index.dbml +0 -0
  83. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/nonexisting_column_in_index.json +0 -0
  84. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/nonexisting_column_in_index_table_partial.dbml +0 -0
  85. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/nonexisting_column_in_index_table_partial.json +0 -0
  86. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/nonexisting_inline_ref_column_in_table.dbml +0 -0
  87. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/nonexisting_inline_ref_column_in_table.json +0 -0
  88. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/nonexisting_inline_ref_column_in_table_partial.dbml +0 -0
  89. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/nonexisting_inline_ref_column_in_table_partial.json +0 -0
  90. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/ref_validator.dbml +0 -0
  91. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/ref_validator.json +0 -0
  92. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/sticky_notes_validator.dbml +0 -0
  93. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/sticky_notes_validator.json +0 -0
  94. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/table_partial.dbml +0 -0
  95. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/table_partial.json +0 -0
  96. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/unknown_table_group_field.dbml +0 -0
  97. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/binder/unknown_table_group_field.json +0 -0
  98. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/array_type.dbml +0 -0
  99. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/array_type.json +0 -0
  100. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/checks.dbml +0 -0
  101. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/checks.json +0 -0
  102. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/circular_ref_1_inline_1_element.dbml +0 -0
  103. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/circular_ref_1_inline_1_element.json +0 -0
  104. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/circular_ref_2_elements.dbml +0 -0
  105. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/circular_ref_2_elements.json +0 -0
  106. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/circular_ref_2_inlines.dbml +0 -0
  107. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/circular_ref_2_inlines.json +0 -0
  108. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/column_caller_type.dbml +0 -0
  109. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/column_caller_type.json +0 -0
  110. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/comment.dbml +0 -0
  111. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/comment.json +0 -0
  112. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/composite_pk.dbml +0 -0
  113. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/composite_pk.json +0 -0
  114. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/default_tables.dbml +0 -0
  115. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/default_tables.json +0 -0
  116. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/dep.dbml +0 -0
  117. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/dep.json +0 -0
  118. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/dep_color.dbml +0 -0
  119. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/dep_color.json +0 -0
  120. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/dep_duplicate.dbml +0 -0
  121. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/dep_duplicate.json +0 -0
  122. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/dep_pipeline.dbml +0 -0
  123. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/dep_pipeline.json +0 -0
  124. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/enum_as_default_column_value.dbml +0 -0
  125. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/enum_as_default_column_value.json +0 -0
  126. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/enum_tables.dbml +0 -0
  127. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/enum_tables.json +0 -0
  128. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/erroneous.dbml +0 -0
  129. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/erroneous.json +0 -0
  130. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/general_schema.dbml +0 -0
  131. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/general_schema.json +0 -0
  132. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/header_color_tables.dbml +0 -0
  133. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/header_color_tables.json +0 -0
  134. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/index_table_partial.dbml +0 -0
  135. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/index_table_partial.json +0 -0
  136. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/index_tables.dbml +0 -0
  137. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/index_tables.json +0 -0
  138. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/metadata.dbml +0 -0
  139. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/metadata.json +0 -0
  140. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/metadata_errors.dbml +0 -0
  141. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/metadata_errors.json +0 -0
  142. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/multi_notes.dbml +0 -0
  143. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/multi_notes.json +0 -0
  144. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/multiline_string.dbml +0 -0
  145. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/multiline_string.json +0 -0
  146. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/negative_number.dbml +0 -0
  147. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/negative_number.json +0 -0
  148. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/note_normalize.dbml +0 -0
  149. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/note_normalize.json +0 -0
  150. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/note_normalize_with_top_empty_lines.dbml +0 -0
  151. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/note_normalize_with_top_empty_lines.json +0 -0
  152. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/old_undocumented_syntax.dbml +0 -0
  153. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/old_undocumented_syntax.json +0 -0
  154. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/primary_key.dbml +0 -0
  155. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/primary_key.json +0 -0
  156. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/project.dbml +0 -0
  157. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/project.json +0 -0
  158. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/ref_name_and_color_setting.dbml +0 -0
  159. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/ref_name_and_color_setting.json +0 -0
  160. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/ref_settings.dbml +0 -0
  161. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/ref_settings.json +0 -0
  162. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/referential_actions.dbml +0 -0
  163. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/referential_actions.json +0 -0
  164. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/self_referential_ref_in_tablepartial.dbml +0 -0
  165. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/self_referential_ref_in_tablepartial.json +0 -0
  166. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/sticky_notes.dbml +0 -0
  167. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/sticky_notes.json +0 -0
  168. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/table_element.dbml +0 -0
  169. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/table_element.json +0 -0
  170. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/table_group.dbml +0 -0
  171. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/table_group.json +0 -0
  172. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/table_group_element.dbml +0 -0
  173. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/table_group_element.json +0 -0
  174. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/table_group_settings.dbml +0 -0
  175. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/table_group_settings.json +0 -0
  176. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/table_partial.dbml +0 -0
  177. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/table_partial.json +0 -0
  178. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/table_reappear_tablegroup.dbml +0 -0
  179. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/table_reappear_tablegroup.json +0 -0
  180. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/table_settings.dbml +0 -0
  181. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/table_settings.json +0 -0
  182. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/tablepartial_causing_circular_ref.dbml +0 -0
  183. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/tablepartial_causing_circular_ref.json +0 -0
  184. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/two_inline_refs.dbml +0 -0
  185. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/interpreter/two_inline_refs.json +0 -0
  186. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/parser/call_expression.dbml +0 -0
  187. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/parser/call_expression.json +0 -0
  188. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/parser/element_in_simple_body.dbml +0 -0
  189. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/parser/element_in_simple_body.json +0 -0
  190. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/parser/erroneous_setting.dbml +0 -0
  191. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/parser/erroneous_setting.json +0 -0
  192. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/parser/expression.dbml +0 -0
  193. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/parser/expression.json +0 -0
  194. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/parser/last_invalid_number.dbml +0 -0
  195. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/parser/last_invalid_number.json +0 -0
  196. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/parser/list_expression.dbml +0 -0
  197. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/parser/list_expression.json +0 -0
  198. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/parser/trailing_comments.dbml +0 -0
  199. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/parser/trailing_comments.json +0 -0
  200. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/parser/tuple_expression.dbml +0 -0
  201. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/parser/tuple_expression.json +0 -0
  202. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/checks.dbml +0 -0
  203. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/checks.json +0 -0
  204. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/complex_names.dbml +0 -0
  205. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/complex_names.json +0 -0
  206. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/dep.dbml +0 -0
  207. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/dep.json +0 -0
  208. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/enum.dbml +0 -0
  209. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/enum.json +0 -0
  210. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/invalid_args.dbml +0 -0
  211. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/invalid_args.json +0 -0
  212. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/public_schema.dbml +0 -0
  213. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/public_schema.json +0 -0
  214. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/redefined_note.dbml +0 -0
  215. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/redefined_note.json +0 -0
  216. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/ref_error_setting.dbml +0 -0
  217. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/ref_error_setting.json +0 -0
  218. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/ref_in_table.dbml +0 -0
  219. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/ref_in_table.json +0 -0
  220. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/schema_nested_tablegroup.dbml +0 -0
  221. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/schema_nested_tablegroup.json +0 -0
  222. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/table_group_settings.dbml +0 -0
  223. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/table_group_settings.json +0 -0
  224. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/table_partial_check.dbml +0 -0
  225. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/table_partial_check.json +0 -0
  226. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/table_partial_settings_general.dbml +0 -0
  227. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/table_partial_settings_general.json +0 -0
  228. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/table_settings_check.dbml +0 -0
  229. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/table_settings_check.json +0 -0
  230. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/table_settings_general.dbml +0 -0
  231. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/table_settings_general.json +0 -0
  232. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/wrong_sub_element_declarations.dbml +0 -0
  233. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/wrong_sub_element_declarations.json +0 -0
  234. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/wrong_table_partial_injection_syntax.dbml +0 -0
  235. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/dbml-ref/validator/wrong_table_partial_injection_syntax.json +0 -0
  236. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/jaffle/LICENSE +0 -0
  237. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/jaffle/README.md +0 -0
  238. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/jaffle/catalog.json +0 -0
  239. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/jaffle/manifest.json +0 -0
  240. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/fixtures/targets/cases.json +0 -0
  241. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/test_agent.py +0 -0
  242. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/test_convert.py +0 -0
  243. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/test_dbml.py +0 -0
  244. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/test_dbml_pipeline.py +0 -0
  245. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/test_dbt.py +0 -0
  246. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/test_diff.py +0 -0
  247. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/test_gallery.py +0 -0
  248. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/test_home_hook.py +0 -0
  249. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/test_mcp.py +0 -0
  250. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/test_packaging.py +0 -0
  251. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/test_parser.py +0 -0
  252. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/test_path.py +0 -0
  253. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/test_render.py +0 -0
  254. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/test_select.py +0 -0
  255. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/test_serve.py +0 -0
  256. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/test_share.py +0 -0
  257. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/test_tags.py +0 -0
  258. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/test_targets.py +0 -0
  259. {quickdbd_cli-0.4.2 → quickdbd_cli-0.5.0}/tests/test_viewer_contract.py +0 -0
@@ -223,3 +223,6 @@ __marimo__/
223
223
  site/
224
224
  jaffle-erd/
225
225
  graphify-out/
226
+
227
+ # Hallmark design-lint records and screenshots
228
+ .hallmark/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: quickdbd-cli
3
- Version: 0.4.2
3
+ Version: 0.5.0
4
4
  Summary: Compile QuickDBD-syntax schema files into interactive HTML ER diagrams, with no table limit.
5
5
  Project-URL: Homepage, https://qdbd.dev/
6
6
  Project-URL: Documentation, https://qdbd.dev/guide/
@@ -193,7 +193,7 @@ jobs:
193
193
  permissions: { contents: read, pull-requests: write }
194
194
  steps:
195
195
  - uses: actions/checkout@v4
196
- - uses: MarkPhamm/quickdbd-cli@v0.4.2
196
+ - uses: MarkPhamm/quickdbd-cli@v0.5.0
197
197
  with:
198
198
  path: erd/ # schema file(s) or folder(s)
199
199
  output: site/index.html
@@ -155,7 +155,7 @@ jobs:
155
155
  permissions: { contents: read, pull-requests: write }
156
156
  steps:
157
157
  - uses: actions/checkout@v4
158
- - uses: MarkPhamm/quickdbd-cli@v0.4.2
158
+ - uses: MarkPhamm/quickdbd-cli@v0.5.0
159
159
  with:
160
160
  path: erd/ # schema file(s) or folder(s)
161
161
  output: site/index.html
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "quickdbd-cli"
7
- version = "0.4.2"
7
+ version = "0.5.0"
8
8
  description = "Compile QuickDBD-syntax schema files into interactive HTML ER diagrams, with no table limit."
9
9
  readme = "README.md"
10
10
  license = "Apache-2.0"
@@ -42,7 +42,7 @@ body {{ width: {w}px; height: {h}px; overflow: hidden; font-family: Geist, Inter
42
42
  .text {{ position: absolute; left: 56px; top: 60px; width: 360px; }}
43
43
  .brand {{ display: flex; align-items: center; gap: 10px; font-weight: 600; font-size: 26px; letter-spacing: -.02em;
44
44
  margin-bottom: 40px; }}
45
- .brand svg {{ color: #2f5bea; }}
45
+ .brand svg {{ color: #2b5797; }}
46
46
  .brand span {{ font: 16px "Geist Mono", monospace; color: #646a75; border: 1px solid rgba(21, 24, 30, .24);
47
47
  border-radius: 6px; padding: 3px 8px; margin-left: 4px; letter-spacing: 0; }}
48
48
  h1 {{ font-size: 48px; line-height: 1.04; font-weight: 600; letter-spacing: -.04em; }}
@@ -0,0 +1 @@
1
+ __version__ = "0.5.0"
@@ -1 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><rect width="128" height="128" rx="28" fill="#2563eb"/><rect x="22" y="22" width="42" height="36" rx="9" fill="#fff"/><path d="M44 58v19a10 10 0 0 0 10 10h12" fill="none" stroke="#fff" stroke-width="8"/><rect x="64" y="70" width="42" height="33" rx="8" fill="#a8c1f7"/></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><rect width="128" height="128" rx="28" fill="#2b5797"/><rect x="22" y="22" width="42" height="36" rx="9" fill="#fff"/><path d="M44 58v19a10 10 0 0 0 10 10h12" fill="none" stroke="#fff" stroke-width="8"/><rect x="64" y="70" width="42" height="33" rx="8" fill="#a9bfdd"/></svg>
@@ -34,8 +34,8 @@
34
34
  --t-edge: #b8bcc2;
35
35
  --row-hl: #dbe6f6;
36
36
  --row-hover: #eef3fa;
37
- --lit: #4361ee;
38
- --lit-deep: #2a3fb8;
37
+ --lit: #2b5797;
38
+ --lit-deep: #1c3a66;
39
39
  }
40
40
  /* Dark theme. viewer.js sets data-theme from the toggle, or from prefers-color-scheme when it's on auto. */
41
41
  :root[data-theme="dark"] {
@@ -32,11 +32,12 @@ def _open(args) -> Project:
32
32
  return Project.open([Path(p) for p in args.paths], Path(args.layout) if getattr(args, "layout", None) else None)
33
33
 
34
34
 
35
+ def _name(p: Path) -> str:
36
+ return p.stem if p.is_file() else (p.resolve().name or "diagram")
37
+
38
+
35
39
  def _title(project: Project) -> str:
36
- if len(project.inputs) == 1:
37
- p = project.inputs[0]
38
- return p.stem if p.is_file() else (p.resolve().name or "diagram")
39
- return "diagram"
40
+ return _name(project.inputs[0]) if len(project.inputs) == 1 else "diagram"
40
41
 
41
42
 
42
43
  def _github_annotation(d: Diagnostic, level: str) -> str:
@@ -76,7 +77,30 @@ def _symbols(schema: Schema) -> dict:
76
77
  return {"tables": tables, "rels": rels}
77
78
 
78
79
 
80
+ def _check_each(args) -> int:
81
+ """Check each PATH on its own, as ``build --site`` builds them; folders with no schema files are skipped."""
82
+ from .project import discover
83
+
84
+ if args.format == "json" or args.stdin_file:
85
+ print("error: --each can't be used with --format json or --stdin-file", file=sys.stderr)
86
+ return 2
87
+ code, checked = 0, 0
88
+ for p in args.paths:
89
+ if Path(p).is_dir() and not discover([Path(p)]):
90
+ print(f"Skipped {p}: no .txt or .dbml schema files", file=sys.stderr)
91
+ continue
92
+ print(f"{p}:")
93
+ code = max(code, cmd_check(argparse.Namespace(**{**vars(args), "paths": [p], "each": False})))
94
+ checked += 1
95
+ if not checked:
96
+ print("error: no schema files found in: " + ", ".join(args.paths), file=sys.stderr)
97
+ return 2
98
+ return code
99
+
100
+
79
101
  def cmd_check(args) -> int:
102
+ if args.each:
103
+ return _check_each(args)
80
104
  project = _open(args)
81
105
  overrides = None
82
106
  if args.stdin_file:
@@ -143,7 +167,52 @@ def _built_page(args) -> tuple[str, dict] | int:
143
167
  return render_page(model, pos, _title(project)), model
144
168
 
145
169
 
170
+ def _build_site(args) -> int:
171
+ """One page per PATH plus an index linking them, in the folder ``args.site``."""
172
+ from urllib.parse import quote
173
+
174
+ from .html import render_index
175
+ from .project import discover
176
+
177
+ if args.layout:
178
+ print("error: --layout can't be used with --site: each PATH uses its own layout file", file=sys.stderr)
179
+ return 2
180
+ pages, seen, failed = [], {}, 0
181
+ for p in map(Path, args.paths):
182
+ if p.is_dir() and not discover([p]):
183
+ print(f"Skipped {p}: no .txt or .dbml schema files", file=sys.stderr)
184
+ continue
185
+ name = _name(p)
186
+ if name.lower() in seen or name.lower() == "index":
187
+ other = seen.get(name.lower(), "the index page")
188
+ print(f"error: {p} and {other} would both be written to {name}.html", file=sys.stderr)
189
+ return 2
190
+ seen[name.lower()] = p
191
+ res = _built_page(argparse.Namespace(**{**vars(args), "paths": [str(p)]}))
192
+ if isinstance(res, int):
193
+ failed = max(failed, res)
194
+ continue
195
+ pages.append((name, *res))
196
+ if failed: # nothing is written, so a failed build never leaves a half-updated site
197
+ return failed
198
+ if not pages:
199
+ print("error: no schema files found in: " + ", ".join(args.paths), file=sys.stderr)
200
+ return 2
201
+ out = Path(args.site)
202
+ out.mkdir(parents=True, exist_ok=True)
203
+ index = []
204
+ for name, page, model in pages:
205
+ (out / f"{name}.html").write_text(page, encoding="utf-8")
206
+ index.append((name, quote(f"{name}.html"), len(model["tables"]), len(model["rels"])))
207
+ print(f"Wrote {out / f'{name}.html'} ({len(model['tables'])} tables, {len(model['rels'])} relationships)")
208
+ (out / "index.html").write_text(render_index(index), encoding="utf-8")
209
+ print(f"Wrote {out / 'index.html'} ({len(pages)} diagrams)")
210
+ return 0
211
+
212
+
146
213
  def cmd_build(args) -> int:
214
+ if args.site:
215
+ return _build_site(args)
147
216
  res = _built_page(args)
148
217
  if isinstance(res, int):
149
218
  return res
@@ -575,11 +644,20 @@ def build_parser() -> argparse.ArgumentParser:
575
644
  metavar="PATH",
576
645
  help="read this schema file's text from stdin instead of disk (an editor's unsaved buffer)",
577
646
  )
647
+ sp.add_argument(
648
+ "--each",
649
+ action="store_true",
650
+ help="check each PATH as its own schema, as build --site does (folders with no schema files are skipped)",
651
+ )
578
652
  sp.set_defaults(func=cmd_check)
579
653
 
580
654
  sp = sub.add_parser("build", help="write an interactive HTML diagram")
581
655
  paths(sp)
582
- sp.add_argument("-o", "--output", default="diagram.html")
656
+ out = sp.add_mutually_exclusive_group()
657
+ out.add_argument("-o", "--output", default="diagram.html")
658
+ out.add_argument(
659
+ "--site", metavar="DIR", help="one page per PATH (named after it) plus an index.html linking them, in DIR"
660
+ )
583
661
  selectors(sp)
584
662
  sp.add_argument(
585
663
  "--diff-base", metavar="GIT_REF", help="colour tables/columns changed since this git ref (e.g. origin/main)"
@@ -190,3 +190,28 @@ def render_page(
190
190
  f"<script>{_asset('viewer.js')}</script>"
191
191
  f"{scripts}</body></html>\n"
192
192
  )
193
+
194
+
195
+ INDEX_CSS = (
196
+ ":root{color-scheme:light dark;--fg:#1f2328;--muted:#656d76;--bg:#fff;--line:#d0d7de}"
197
+ "@media (prefers-color-scheme:dark){:root{--fg:#e6edf3;--muted:#8d96a0;--bg:#0d1117;--line:#30363d}}"
198
+ "body{margin:0;background:var(--bg);color:var(--fg);font:15px/1.5 system-ui,sans-serif}"
199
+ "main{max-width:640px;margin:0 auto;padding:32px 16px}h1{font-size:20px;margin:0 0 16px}"
200
+ "ul{list-style:none;margin:0;padding:0}li{border-top:1px solid var(--line);padding:10px 0}"
201
+ "a{color:inherit;font-weight:600}span{color:var(--muted);margin-left:8px}"
202
+ )
203
+
204
+
205
+ def render_index(pages: list[tuple[str, str, int, int]], title: str = "Diagrams") -> str:
206
+ """``qdbd build --site``'s index: a link per (name, href, tables, relationships)."""
207
+ items = "".join(
208
+ f'<li><a href="{_escape(href)}">{_escape(name)}</a><span>{t} tables, {r} relationships</span></li>'
209
+ for name, href, t, r in pages
210
+ )
211
+ return (
212
+ '<!doctype html>\n<html lang="en"><head><meta charset="utf-8">'
213
+ '<meta name="viewport" content="width=device-width, initial-scale=1">'
214
+ '<meta name="generator" content="qdbd">'
215
+ f"{favicon()}<title>{_escape(title)}</title><style>{INDEX_CSS}</style></head>"
216
+ f"<body><main><h1>{_escape(title)}</h1><ul>{items}</ul></main></body></html>\n"
217
+ )
@@ -252,6 +252,55 @@ def test_build_is_deterministic_and_does_not_write_sidecar(tmp_path):
252
252
  assert '<link rel="icon" href="data:image/svg+xml,%3Csvg ' in html
253
253
 
254
254
 
255
+ def test_build_site_writes_a_page_per_path_and_an_index(tmp_path, capsys):
256
+ for name in ("sales", "hr"):
257
+ (tmp_path / "erd" / name).mkdir(parents=True)
258
+ (tmp_path / "erd" / name / "s.txt").write_text(SMALL)
259
+ (tmp_path / "erd" / "empty").mkdir()
260
+ site = tmp_path / "public"
261
+ dirs = [str(tmp_path / "erd" / n) for n in ("hr", "empty", "sales")]
262
+ assert main(["build", *dirs, "--site", str(site)]) == 0
263
+ assert sorted(f.name for f in site.iterdir()) == ["hr.html", "index.html", "sales.html"]
264
+ assert "<title>hr</title>" in (site / "hr.html").read_text()
265
+ index = (site / "index.html").read_text()
266
+ assert index.index('href="hr.html"') < index.index('href="sales.html"')
267
+ assert "2 tables, 1 relationships" in index
268
+ assert "Skipped" in capsys.readouterr().err
269
+
270
+
271
+ def test_check_each_keeps_namespaces_apart(tmp_path, capsys):
272
+ for name in ("sales", "hr"):
273
+ (tmp_path / name).mkdir()
274
+ (tmp_path / name / "s.txt").write_text(SMALL)
275
+ (tmp_path / "empty").mkdir()
276
+ dirs = [str(tmp_path / n) for n in ("hr", "empty", "sales")]
277
+ assert main(["check", *dirs]) == 1 # one namespace: Customer and Order are duplicates
278
+ assert main(["check", "--each", *dirs]) == 0
279
+ assert main(["check", "--each", str(tmp_path / "empty")]) == 2
280
+ assert main(["check", "--each", "--format", "json", *dirs]) == 2
281
+ capsys.readouterr()
282
+
283
+
284
+ def test_build_site_writes_nothing_when_a_schema_fails(tmp_path):
285
+ (tmp_path / "ok").mkdir()
286
+ (tmp_path / "ok" / "s.txt").write_text(SMALL)
287
+ (tmp_path / "bad").mkdir()
288
+ (tmp_path / "bad" / "s.txt").write_text("Order\n-\nId int FK >- Missing.Id\n")
289
+ site = tmp_path / "public"
290
+ assert main(["build", str(tmp_path / "ok"), str(tmp_path / "bad"), "--site", str(site)]) == 1
291
+ assert not site.exists()
292
+
293
+
294
+ def test_build_site_refuses_clashing_names(tmp_path, capsys):
295
+ for d in ("a/sales", "b/sales"):
296
+ (tmp_path / d).mkdir(parents=True)
297
+ (tmp_path / d / "s.txt").write_text(SMALL)
298
+ assert main(["build", str(tmp_path / "a/sales"), str(tmp_path / "b/sales"), "--site", str(tmp_path / "o")]) == 2
299
+ assert "both be written to sales.html" in capsys.readouterr().err
300
+ with pytest.raises(SystemExit):
301
+ main(["build", str(tmp_path / "a/sales"), "-o", "x.html", "--site", str(tmp_path / "o")])
302
+
303
+
255
304
  def test_layout_command_writes_sidecar_and_reset(tmp_path):
256
305
  f = tmp_path / "s.txt"
257
306
  f.write_text(SMALL)
@@ -1 +0,0 @@
1
- __version__ = "0.4.2"
File without changes
File without changes