archsight 0.3.2 → 0.4.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.
- checksums.yaml +4 -4
- data/README.md +7 -1
- data/docs/archimate.md +21 -1
- data/docs/configuration.md +1 -0
- data/docs/diagram.md +15 -3
- data/docs/docker.md +4 -1
- data/docs/icons.md +32 -0
- data/docs/import.md +178 -55
- data/docs/index.md.erb +31 -8
- data/docs/modeling.md +772 -24
- data/docs/pages.md +44 -13
- data/docs/search.md +21 -1
- data/docs/togaf.md +5 -1
- data/lib/archsight/analysis/result.rb +8 -2
- data/lib/archsight/analysis/sandbox.rb +8 -0
- data/lib/archsight/analysis/typst_renderer.rb +246 -0
- data/lib/archsight/analysis.rb +1 -0
- data/lib/archsight/annotations/annotation.rb +30 -3
- data/lib/archsight/annotations/architecture_annotations.rb +47 -0
- data/lib/archsight/annotations/asset_annotations.rb +34 -0
- data/lib/archsight/annotations/link_annotations.rb +15 -0
- data/lib/archsight/annotations/resource_reference.rb +12 -0
- data/lib/archsight/annotations/risk_annotations.rb +21 -0
- data/lib/archsight/cli.rb +124 -23
- data/lib/archsight/database.rb +40 -0
- data/lib/archsight/diagram/cli.rb +50 -2
- data/lib/archsight/diagram/formatter.rb +112 -0
- data/lib/archsight/diagram/routing/edge_router/orthogonal_path.rb +38 -10
- data/lib/archsight/diagram/routing/edge_router.rb +29 -4
- data/lib/archsight/diagram/routing/edge_routing.rb +61 -5
- data/lib/archsight/diagram/style/theme.rb +7 -2
- data/lib/archsight/documentation.rb +3 -2
- data/lib/archsight/editor/page_source.rb +13 -1
- data/lib/archsight/export/confluence/analysis_output.rb +101 -0
- data/lib/archsight/export/confluence/client.rb +13 -0
- data/lib/archsight/export/confluence/diagram_links.rb +1 -1
- data/lib/archsight/export/confluence/exporter.rb +40 -13
- data/lib/archsight/export/confluence/labels.rb +25 -0
- data/lib/archsight/export/confluence/page_properties.rb +4 -6
- data/lib/archsight/export/confluence/storage.rb +38 -2
- data/lib/archsight/helpers/embeds.rb +18 -7
- data/lib/archsight/helpers/resource_resolver.rb +25 -0
- data/lib/archsight/import/executor.rb +139 -16
- data/lib/archsight/import/handler.rb +55 -6
- data/lib/archsight/import/handler_loader.rb +64 -0
- data/lib/archsight/import/handlers/cache_pruner.rb +30 -7
- data/lib/archsight/import/handlers/command.rb +120 -0
- data/lib/archsight/import/handlers/github.rb +4 -1
- data/lib/archsight/import/handlers/gitlab.rb +4 -1
- data/lib/archsight/import/handlers/go_dep_resolver.rb +10 -2
- data/lib/archsight/import/handlers/go_grapher.rb +102 -5
- data/lib/archsight/import/handlers/go_module_parser.rb +88 -0
- data/lib/archsight/import/handlers/grapher.rb +40 -1
- data/lib/archsight/import/handlers/repository.rb +3 -0
- data/lib/archsight/import/handlers/rest_api_index.rb +3 -0
- data/lib/archsight/import/registry.rb +22 -1
- data/lib/archsight/import.rb +64 -1
- data/lib/archsight/linter/structure.rb +239 -0
- data/lib/archsight/linter.rb +217 -6
- data/lib/archsight/page_loader.rb +12 -1
- data/lib/archsight/query/evaluator.rb +13 -6
- data/lib/archsight/query/parser.rb +73 -6
- data/lib/archsight/query.rb +1 -1
- data/lib/archsight/references.rb +3 -3
- data/lib/archsight/renderer.rb +80 -23
- data/lib/archsight/resources/analysis.rb +3 -2
- data/lib/archsight/resources/application_component.rb +83 -8
- data/lib/archsight/resources/application_event.rb +79 -0
- data/lib/archsight/resources/application_service.rb +18 -2
- data/lib/archsight/resources/base.rb +58 -5
- data/lib/archsight/resources/business_actor.rb +14 -1
- data/lib/archsight/resources/business_contract.rb +72 -0
- data/lib/archsight/resources/business_control.rb +10 -2
- data/lib/archsight/resources/business_event.rb +79 -0
- data/lib/archsight/resources/business_process.rb +8 -1
- data/lib/archsight/resources/business_product.rb +12 -0
- data/lib/archsight/resources/business_role.rb +70 -0
- data/lib/archsight/resources/compliance_evidence.rb +8 -2
- data/lib/archsight/resources/data_object.rb +6 -1
- data/lib/archsight/resources/implementation_deliverable.rb +63 -0
- data/lib/archsight/resources/implementation_event.rb +52 -0
- data/lib/archsight/resources/implementation_gap.rb +49 -0
- data/lib/archsight/resources/implementation_plateau.rb +67 -0
- data/lib/archsight/resources/implementation_work_package.rb +84 -0
- data/lib/archsight/resources/import.rb +37 -11
- data/lib/archsight/resources/location.rb +56 -0
- data/lib/archsight/resources/motivation_assessment.rb +121 -0
- data/lib/archsight/resources/motivation_constraint.rb +7 -1
- data/lib/archsight/resources/motivation_driver.rb +50 -0
- data/lib/archsight/resources/motivation_goal.rb +13 -1
- data/lib/archsight/resources/motivation_principle.rb +75 -0
- data/lib/archsight/resources/motivation_requirement.rb +18 -2
- data/lib/archsight/resources/motivation_stakeholder.rb +21 -0
- data/lib/archsight/resources/page.rb +9 -7
- data/lib/archsight/resources/strategy_capability.rb +9 -0
- data/lib/archsight/resources/technology_artifact.rb +11 -4
- data/lib/archsight/resources/technology_communication_network.rb +89 -0
- data/lib/archsight/resources/technology_device.rb +88 -0
- data/lib/archsight/resources/technology_equipment.rb +75 -0
- data/lib/archsight/resources/technology_event.rb +80 -0
- data/lib/archsight/resources/technology_facility.rb +70 -0
- data/lib/archsight/resources/technology_node.rb +57 -1
- data/lib/archsight/resources/technology_service.rb +33 -0
- data/lib/archsight/resources/technology_system_software.rb +28 -0
- data/lib/archsight/resources.rb +12 -0
- data/lib/archsight/version.rb +1 -1
- data/lib/archsight/web/api/analysis_helpers.rb +55 -0
- data/lib/archsight/web/api/json_helpers.rb +3 -37
- data/lib/archsight/web/api/openapi/spec.yaml +10 -8
- data/lib/archsight/web/api/page_helpers.rb +1 -8
- data/lib/archsight/web/api/routes.rb +7 -2
- data/lib/archsight/web/application.rb +38 -2
- data/lib/archsight/web/editor/routes.rb +2 -1
- data/lib/archsight/web/public/vue/ApiDocsPage-COp4onwn.js +1 -0
- data/lib/archsight/web/public/vue/DocPage-D52OwaKc.js +1 -0
- data/lib/archsight/web/public/vue/EditorPage-3aqL7yVf.js +35 -0
- data/lib/archsight/web/public/vue/ErrorPage--b9XeSYa.js +2 -0
- data/lib/archsight/web/public/vue/GraphView-qh_EtRrQ.js +1 -0
- data/lib/archsight/web/public/vue/HomePage-C2TNh2U-.js +2 -0
- data/lib/archsight/web/public/vue/InstanceRouter-ZaCcjlIX.css +1 -0
- data/lib/archsight/web/public/vue/InstanceRouter-uzb_OMG0.js +1 -0
- data/lib/archsight/web/public/vue/KindList-CyJuP_uq.js +1 -0
- data/lib/archsight/web/public/vue/KindList-yYcRT2BV.css +1 -0
- data/lib/archsight/web/public/vue/PageView-B93woeN3.css +1 -0
- data/lib/archsight/web/public/vue/PageView-FyygrS-b.js +1 -0
- data/lib/archsight/web/public/vue/QueryError-B4Ex_csZ.js +1 -0
- data/lib/archsight/web/public/vue/ResourceList-BY6Z1Kcb.js +2 -0
- data/lib/archsight/web/public/vue/ResourceList-D75O87zG.css +1 -0
- data/lib/archsight/web/public/vue/{SearchResults-CyPUZZSC.css → SearchResults-BV6UHriJ.css} +1 -1
- data/lib/archsight/web/public/vue/SearchResults-CkFpHF8m.js +1 -0
- data/lib/archsight/web/public/vue/WikiPage-BoHNewCX.js +3 -0
- data/lib/archsight/web/public/vue/WikiPage-TpmM1VAF.css +1 -0
- data/lib/archsight/web/public/vue/architecture-7GRP2DOG-BvzKZE4e.js +1 -0
- data/lib/archsight/web/public/vue/cynefin-OW5HDTMX-D-xs_Hxh.js +1 -0
- data/lib/archsight/web/public/vue/eventmodeling-NTZA5JFV-nbjxG01S.js +1 -0
- data/lib/archsight/web/public/vue/gitGraph-4MIJSDKK-CW6mw2ab.js +1 -0
- data/lib/archsight/web/public/vue/index-BGlYCbi7.js +3 -0
- data/lib/archsight/web/public/vue/index-eUHmJ7K2.css +1 -0
- data/lib/archsight/web/public/vue/info-A6RAGUB7-C12sjlHe.js +1 -0
- data/lib/archsight/web/public/vue/{mermaid-BjEi5URd.js → mermaid-DjsXQ_XN.js} +35 -35
- data/lib/archsight/web/public/vue/packet-AYTQ26CC-wMwKwHmA.js +1 -0
- data/lib/archsight/web/public/vue/pie-WAS4IAKB-w1-sAU_K.js +1 -0
- data/lib/archsight/web/public/vue/radar-RG4KPBEZ-DpwqIFoy.js +1 -0
- data/lib/archsight/web/public/vue/railroad-74A4TZTK-Ce5XC24d.js +1 -0
- data/lib/archsight/web/public/vue/railroad-abnf-HS5TGJTU-BSQO2pds.js +1 -0
- data/lib/archsight/web/public/vue/railroad-ebnf-LZEXJU2U-Dq1c2YtD.js +1 -0
- data/lib/archsight/web/public/vue/railroad-peg-WCYAUIDC-DKj6dli0.js +1 -0
- data/lib/archsight/web/public/vue/rolldown-runtime-hePW80VL.js +1 -0
- data/lib/archsight/web/public/vue/treeView-Q6P3EWNA-BmHNTWxU.js +1 -0
- data/lib/archsight/web/public/vue/treemap-WGGIJYW6-DsEI7sSD.js +1 -0
- data/lib/archsight/web/public/vue/{useGraphviz-DweKV7Kg.js → useGraphviz-4evusK9i.js} +13 -1
- data/lib/archsight/web/public/vue/{useHighlight-D5Gf8DLl.js → useHighlight-DPguaxfm.js} +8 -8
- data/lib/archsight/web/public/vue/usePanZoom-seQE1TPk.js +12 -0
- data/lib/archsight/web/public/vue/wardley-WFR3VGLG-CSCW83-M.js +1 -0
- data/lib/archsight/web/public/vue.html +5 -5
- metadata +72 -38
- data/lib/archsight/web/public/vue/ApiDocsPage-DoOxKjG0.js +0 -1
- data/lib/archsight/web/public/vue/DocPage-CfsC3CeQ.js +0 -1
- data/lib/archsight/web/public/vue/EditorPage-CsJA0q8n.js +0 -35
- data/lib/archsight/web/public/vue/ErrorPage-OJpJz9df.js +0 -2
- data/lib/archsight/web/public/vue/GraphView-CBq6oFRV.js +0 -1
- data/lib/archsight/web/public/vue/HomePage-BwgMLgVC.js +0 -2
- data/lib/archsight/web/public/vue/InstanceRouter-DQz-SsQq.js +0 -1
- data/lib/archsight/web/public/vue/InstanceRouter-jeavM6PW.css +0 -1
- data/lib/archsight/web/public/vue/KindList-4q0K9Cll.js +0 -1
- data/lib/archsight/web/public/vue/PageView-DzeGnvoS.js +0 -1
- data/lib/archsight/web/public/vue/QueryError-kg6Yf-pW.js +0 -1
- data/lib/archsight/web/public/vue/ResourceList-B0FLaFR3.css +0 -1
- data/lib/archsight/web/public/vue/ResourceList-Df_0e0qt.js +0 -2
- data/lib/archsight/web/public/vue/SearchResults-CKgY6_wH.js +0 -1
- data/lib/archsight/web/public/vue/WikiPage-DoFJ0dbW.css +0 -1
- data/lib/archsight/web/public/vue/WikiPage-DrvCHwJ7.js +0 -13
- data/lib/archsight/web/public/vue/architecture-7GRP2DOG-BfA1TPxQ.js +0 -1
- data/lib/archsight/web/public/vue/cynefin-OW5HDTMX-BmgdUKVD.js +0 -1
- data/lib/archsight/web/public/vue/eventmodeling-NTZA5JFV-DbXDvAWF.js +0 -1
- data/lib/archsight/web/public/vue/gitGraph-4MIJSDKK-BkVhrKS1.js +0 -1
- data/lib/archsight/web/public/vue/index-D0Q5GZRs.js +0 -3
- data/lib/archsight/web/public/vue/index-oF-iyZvk.css +0 -1
- data/lib/archsight/web/public/vue/info-A6RAGUB7-BIlCVuUY.js +0 -1
- data/lib/archsight/web/public/vue/packet-AYTQ26CC-eoQTjY3j.js +0 -1
- data/lib/archsight/web/public/vue/pie-WAS4IAKB-DEOotGhh.js +0 -1
- data/lib/archsight/web/public/vue/radar-RG4KPBEZ-C2yucuUN.js +0 -1
- data/lib/archsight/web/public/vue/railroad-74A4TZTK-CzONK5VY.js +0 -1
- data/lib/archsight/web/public/vue/railroad-abnf-HS5TGJTU-9zRPsDsx.js +0 -1
- data/lib/archsight/web/public/vue/railroad-ebnf-LZEXJU2U-BJ4dkz9l.js +0 -1
- data/lib/archsight/web/public/vue/railroad-peg-WCYAUIDC-DFy_rqAj.js +0 -1
- data/lib/archsight/web/public/vue/treeView-Q6P3EWNA-2cq5CyD2.js +0 -1
- data/lib/archsight/web/public/vue/treemap-WGGIJYW6-DK-e9Ez4.js +0 -1
- data/lib/archsight/web/public/vue/wardley-WFR3VGLG-BQwqUqfB.js +0 -1
|
@@ -66,7 +66,8 @@ module Archsight::Web::API::JsonHelpers
|
|
|
66
66
|
description: klass.description,
|
|
67
67
|
layer: klass.layer,
|
|
68
68
|
icon: klass.icon,
|
|
69
|
-
instance_count: count
|
|
69
|
+
instance_count: count,
|
|
70
|
+
self_relations: Archsight::GraphvisRenderer.self_relations(klass).any?
|
|
70
71
|
}
|
|
71
72
|
end
|
|
72
73
|
kinds.sort_by { |k| k[:kind] }
|
|
@@ -92,6 +93,7 @@ module Archsight::Web::API::JsonHelpers
|
|
|
92
93
|
name: instance.name,
|
|
93
94
|
metadata: { annotations: render_annotations(instance.annotations, base: Archsight::Assets.base_dir_for(instance, resources_dir: Archsight.resources_dir), kind: kind) },
|
|
94
95
|
annotation_formats: Archsight::Resources[kind]&.annotation_formats(instance.annotations.keys) || {},
|
|
96
|
+
annotation_links: Archsight::Helpers::ResourceResolver.new(db).annotation_links(kind, instance.annotations),
|
|
95
97
|
spec: serialize_spec(instance.spec),
|
|
96
98
|
relations: extract_relations(instance),
|
|
97
99
|
references: extract_references(instance),
|
|
@@ -193,42 +195,6 @@ module Archsight::Web::API::JsonHelpers
|
|
|
193
195
|
end
|
|
194
196
|
end
|
|
195
197
|
|
|
196
|
-
def build_analysis_result(result)
|
|
197
|
-
data = {
|
|
198
|
-
name: result.name,
|
|
199
|
-
success: result.success?,
|
|
200
|
-
has_findings: result.has_findings?,
|
|
201
|
-
duration: result.duration,
|
|
202
|
-
sections: result.sections.map { |s| serialize_analysis_section(s) }
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
if result.failed?
|
|
206
|
-
data[:error] = result.error
|
|
207
|
-
data[:error_backtrace] = result.error_backtrace if result.error_backtrace&.any?
|
|
208
|
-
end
|
|
209
|
-
|
|
210
|
-
data
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
def serialize_analysis_section(section)
|
|
214
|
-
case section[:type]
|
|
215
|
-
when :heading
|
|
216
|
-
{ type: "heading", level: section[:level], text: section[:text] }
|
|
217
|
-
when :text
|
|
218
|
-
{ type: "text", content: markdown(section[:content]) }
|
|
219
|
-
when :message
|
|
220
|
-
{ type: "message", level: section[:level].to_s, message: section[:message] }
|
|
221
|
-
when :table
|
|
222
|
-
{ type: "table", headers: section[:headers], rows: section[:rows] }
|
|
223
|
-
when :list
|
|
224
|
-
{ type: "list", items: section[:items] }
|
|
225
|
-
when :code
|
|
226
|
-
{ type: "code", lang: section[:lang], content: section[:content] }
|
|
227
|
-
else
|
|
228
|
-
{ type: section[:type].to_s }
|
|
229
|
-
end
|
|
230
|
-
end
|
|
231
|
-
|
|
232
198
|
def extract_references(instance)
|
|
233
199
|
references = {}
|
|
234
200
|
|
|
@@ -254,7 +254,7 @@ paths:
|
|
|
254
254
|
Returns one page with its metadata and its body rendered to HTML.
|
|
255
255
|
|
|
256
256
|
**Metadata** comes from the frontmatter: `title` (falls back to the name), `status`, `author` and
|
|
257
|
-
`owner` (`Name <email>`, split into `name` and `email`), `tags` and the `
|
|
257
|
+
`owner` (`Name <email>`, split into `name` and `email`), `tags` and the `links` (name and URL, e.g. `confluence`).
|
|
258
258
|
|
|
259
259
|
**`html`** is the markdown body rendered once per request:
|
|
260
260
|
- GitHub-flavoured markdown (tables, fenced code, task lists).
|
|
@@ -309,7 +309,7 @@ paths:
|
|
|
309
309
|
owner:
|
|
310
310
|
name: Jane Doe
|
|
311
311
|
email: jane.doe@example.com
|
|
312
|
-
|
|
312
|
+
links: {}
|
|
313
313
|
tags:
|
|
314
314
|
- howto
|
|
315
315
|
- wiki
|
|
@@ -1489,7 +1489,7 @@ components:
|
|
|
1489
1489
|
description: Whether the analysis executed successfully
|
|
1490
1490
|
has_findings:
|
|
1491
1491
|
type: boolean
|
|
1492
|
-
description: Whether the
|
|
1492
|
+
description: Whether the script produced any output (tables, lists, text, ...). Output is not a problem; errors and warnings the script reports are message sections
|
|
1493
1493
|
duration:
|
|
1494
1494
|
type: number
|
|
1495
1495
|
format: float
|
|
@@ -1869,7 +1869,7 @@ components:
|
|
|
1869
1869
|
|
|
1870
1870
|
PageResponse:
|
|
1871
1871
|
type: object
|
|
1872
|
-
required: [name, title, status, author, owner, created, updated, properties,
|
|
1872
|
+
required: [name, title, status, author, owner, created, updated, properties, links, tags, toc, breadcrumb, html, backlinks]
|
|
1873
1873
|
properties:
|
|
1874
1874
|
name:
|
|
1875
1875
|
type: string
|
|
@@ -1909,10 +1909,12 @@ components:
|
|
|
1909
1909
|
html:
|
|
1910
1910
|
type: string
|
|
1911
1911
|
description: The value rendered as inline markdown (links, emphasis, `{macros}`, `[[wiki links]]`), without a paragraph around it
|
|
1912
|
-
|
|
1913
|
-
type:
|
|
1914
|
-
|
|
1915
|
-
|
|
1912
|
+
links:
|
|
1913
|
+
type: object
|
|
1914
|
+
description: Links of the page to other systems, by name (`confluence`, `jira`, ...)
|
|
1915
|
+
additionalProperties:
|
|
1916
|
+
type: string
|
|
1917
|
+
format: uri
|
|
1916
1918
|
tags:
|
|
1917
1919
|
type: array
|
|
1918
1920
|
items:
|
|
@@ -41,7 +41,7 @@ module Archsight::Web::API::PageHelpers
|
|
|
41
41
|
created: annotations["page/created"],
|
|
42
42
|
updated: annotations["page/updated"],
|
|
43
43
|
properties: page.properties.map { |key, value| { key: key, value: value, html: inline_markdown(value, page) } },
|
|
44
|
-
|
|
44
|
+
links: annotations.select { |key, _| key.start_with?("link/") }.transform_keys { |key| key.delete_prefix("link/") },
|
|
45
45
|
tags: Archsight::Resources::Page.annotation_matching("page/tags")&.value_for(page) || [],
|
|
46
46
|
toc: annotations["page/toc"] == "yes" ? Archsight::PageTree.toc(body) : [],
|
|
47
47
|
breadcrumb: tree.breadcrumb(page),
|
|
@@ -50,13 +50,6 @@ module Archsight::Web::API::PageHelpers
|
|
|
50
50
|
}
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
-
# A short text (a page property) rendered as inline markdown: links, emphasis, `{macros}`, [[wiki links]], without the
|
|
54
|
-
# paragraph around it
|
|
55
|
-
def inline_markdown(text, page)
|
|
56
|
-
html = markdown(text.to_s, base: Archsight::Assets.base_dir_for(page, resources_dir: Archsight.resources_dir), page: page)
|
|
57
|
-
html.strip.sub(%r{\A<p>(.*)</p>\z}m, '\1')
|
|
58
|
-
end
|
|
59
|
-
|
|
60
53
|
# The header already shows the title, so a leading "# Title" that repeats it is dropped
|
|
61
54
|
# (Confluence exports and hand-written pages usually start with one).
|
|
62
55
|
def strip_duplicate_title(body, page)
|
|
@@ -5,6 +5,7 @@ require "sinatra/extension"
|
|
|
5
5
|
require_relative "json_helpers"
|
|
6
6
|
require_relative "page_helpers"
|
|
7
7
|
require_relative "requirements_helpers"
|
|
8
|
+
require_relative "analysis_helpers"
|
|
8
9
|
require_relative "../../assets"
|
|
9
10
|
|
|
10
11
|
module Archsight; end
|
|
@@ -18,6 +19,7 @@ module Archsight::Web::API::Routes
|
|
|
18
19
|
helpers Archsight::Web::API::JsonHelpers
|
|
19
20
|
helpers Archsight::Web::API::PageHelpers
|
|
20
21
|
helpers Archsight::Web::API::RequirementsHelpers
|
|
22
|
+
helpers Archsight::Web::API::AnalysisHelpers
|
|
21
23
|
|
|
22
24
|
# Rendering is CPU work, previews are typed, not pasted
|
|
23
25
|
MAX_DIAGRAM_SOURCE = 100_000
|
|
@@ -67,10 +69,13 @@ module Archsight::Web::API::Routes
|
|
|
67
69
|
klass = Archsight::Resources[kind]
|
|
68
70
|
json_error("Kind '#{kind}' not found", status: 404, error_type: "NotFound") unless klass
|
|
69
71
|
|
|
70
|
-
|
|
72
|
+
# an alias finds the one resource that has it; the response carries the real name
|
|
73
|
+
instance = db.instance_by_kind(kind, name) || db.instance_by_alias(kind, name)
|
|
71
74
|
json_error("Instance '#{name}' not found", status: 404, error_type: "NotFound") unless instance
|
|
72
75
|
|
|
73
|
-
|
|
76
|
+
# graph_layers: the layers its dependency graph follows when the page opens
|
|
77
|
+
json_response(build_instance_response(kind, instance)
|
|
78
|
+
.merge(graph_layers: Archsight::GraphvisRenderer.default_graph_layers(instance.class.layer)))
|
|
74
79
|
end
|
|
75
80
|
|
|
76
81
|
# GET /api/v1/pages - Page tree built from PageMenu resources, page tags and filters and the home page
|
|
@@ -25,17 +25,25 @@ class Archsight::Web::Application < Sinatra::Base
|
|
|
25
25
|
attr_accessor :db
|
|
26
26
|
|
|
27
27
|
def database
|
|
28
|
-
@database ||= Archsight::Database.new(Archsight.resources_dir).tap(&:reload!)
|
|
28
|
+
@database ||= Archsight::Database.new(Archsight.resources_dir).tap(&:reload!).tap { |db| load_import_handlers(db) }
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
def reload!
|
|
32
32
|
start = Time.new
|
|
33
33
|
puts "== Reloading ..." if database.verbose
|
|
34
34
|
database.reload!
|
|
35
|
+
load_import_handlers(database)
|
|
35
36
|
dur = (Time.new - start) * 1000
|
|
36
37
|
puts format("== done %0.2f ms", dur) if database.verbose
|
|
37
38
|
end
|
|
38
39
|
|
|
40
|
+
# The import handlers, built-in and of the resources repository (import/handlerPath), so the editor knows the
|
|
41
|
+
# same handler names as `archsight lint`. A file that does not load is reported, the server keeps running.
|
|
42
|
+
def load_import_handlers(db)
|
|
43
|
+
require "archsight/import"
|
|
44
|
+
Archsight::Import::HandlerLoader.load(db).each { |problem| warn "Import handler: #{problem}" }
|
|
45
|
+
end
|
|
46
|
+
|
|
39
47
|
# Configure application for the given environment
|
|
40
48
|
# @param env [Symbol] :development or :production
|
|
41
49
|
# @param logging [Boolean, nil] Override default logging setting
|
|
@@ -135,6 +143,15 @@ class Archsight::Web::Application < Sinatra::Base
|
|
|
135
143
|
settings.environment == :development
|
|
136
144
|
end
|
|
137
145
|
|
|
146
|
+
# A short text (a page property, an analysis table cell) rendered as inline markdown: links, emphasis,
|
|
147
|
+
# `{macros}`, [[wiki links]], without the paragraph around it
|
|
148
|
+
# @param page [Archsight::Resources::Page, nil] the page the text belongs to, for its relative images and macros
|
|
149
|
+
def inline_markdown(text, page = nil)
|
|
150
|
+
base = page && Archsight::Assets.base_dir_for(page, resources_dir: Archsight.resources_dir)
|
|
151
|
+
html = markdown(text.to_s, base: base, page: page)
|
|
152
|
+
html.strip.sub(%r{\A<p>(.*)</p>\z}m, '\1')
|
|
153
|
+
end
|
|
154
|
+
|
|
138
155
|
# Render markdown to HTML with optional URL resolution for repository content
|
|
139
156
|
# @param data [String] Markdown content
|
|
140
157
|
# @param git_url [String, nil] Git URL for resolving relative paths (e.g., for README images)
|
|
@@ -282,14 +299,33 @@ class Archsight::Web::Application < Sinatra::Base
|
|
|
282
299
|
serve_vue
|
|
283
300
|
end
|
|
284
301
|
|
|
302
|
+
# The resources of a kind and the relations between them (see GraphvisRenderer#create_graph_kind)
|
|
303
|
+
get "/kinds/:kind/dot" do
|
|
304
|
+
halt 404, "kind #{params["kind"]} unknown" unless Archsight::Resources[params["kind"]]
|
|
305
|
+
|
|
306
|
+
content_type "text/plain"
|
|
307
|
+
create_graph_kind(db, params["kind"])
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
# An alias in the URL redirects to the resource's real name (`:` stays readable, the rest is escaped)
|
|
285
311
|
get "/kinds/:kind/instances/:instance" do
|
|
312
|
+
kind = params["kind"]
|
|
313
|
+
name = params["instance"]
|
|
314
|
+
if Archsight::Resources[kind] && !db.instance_by_kind(kind, name) && (instance = db.instance_by_alias(kind, name))
|
|
315
|
+
redirect "/kinds/#{kind}/instances/#{ERB::Util.url_encode(instance.name).gsub("%3A", ":")}"
|
|
316
|
+
end
|
|
317
|
+
|
|
286
318
|
serve_vue
|
|
287
319
|
end
|
|
288
320
|
|
|
321
|
+
# `depth`: steps from the instance (a positive number; missing or `all`: every step), `layers`: the layers it
|
|
322
|
+
# follows, comma separated (missing or none known: every layer)
|
|
289
323
|
get "/kinds/:kind/instances/:instance/dot" do
|
|
290
324
|
@kind = params["kind"]
|
|
291
325
|
@instance = params["instance"]
|
|
326
|
+
depth = params["depth"].to_s.match?(/\A[1-9]\d*\z/) ? params["depth"].to_i : nil
|
|
327
|
+
layers = params["layers"].to_s.split(",").map(&:strip) & Archsight::Resources::LAYERS
|
|
292
328
|
content_type "text/plain"
|
|
293
|
-
create_graph_one(db, @kind, @instance)
|
|
329
|
+
create_graph_one(db, @kind, @instance, max_depth: depth, layers: layers.empty? ? nil : layers)
|
|
294
330
|
end
|
|
295
331
|
end
|
|
@@ -57,7 +57,8 @@ module Archsight
|
|
|
57
57
|
data = build_form_metadata(kind, klass)
|
|
58
58
|
data[:mode] = "edit"
|
|
59
59
|
data[:name] = instance.name
|
|
60
|
-
|
|
60
|
+
# defaults are not in the file, a save leaves them out
|
|
61
|
+
data[:annotations] = instance.annotations.reject { |key, _| instance.defaulted?(key) }
|
|
61
62
|
data[:relations] = extract_instance_relations(instance)
|
|
62
63
|
data[:path_ref] = source_ref(instance)
|
|
63
64
|
data[:content_hash] = source_content_hash(instance)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{F as e,I as t,K as n,N as r,T as i,W as a,et as o,i as s,it as c,k as l,tt as u}from"./index-BGlYCbi7.js";var d={class:`api-docs-page`},f={key:0,class:`pico-color-red-500`},p=s({__name:`ApiDocsPage`,setup(s){let p=i(),m=o(null),h=o(null);function g(e){return new Promise((t,n)=>{if(window.Redoc)return t();let r=document.createElement(`script`);r.src=e,r.onload=t,r.onerror=()=>n(Error(`Failed to load ReDoc`)),document.head.appendChild(r)})}return a(async()=>{try{await g(`https://cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js`),window.Redoc.init(`/api/v1/openapi.yaml`,{},m.value)}catch(e){h.value=e.message}}),(i,a)=>(n(),t(`div`,d,[r(`a`,{href:`#`,class:`back-link`,onClick:a[0]||=l(e=>u(p).back(),[`prevent`])},`← Back`),h.value?(n(),t(`div`,f,c(h.value),1)):e(``,!0),r(`div`,{ref_key:`container`,ref:m},null,512)]))}},[[`__scopeId`,`data-v-4823b89b`]]);export{p as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{I as e,K as t,N as n,P as r,Z as i,et as a,t as o,u as s}from"./index-BGlYCbi7.js";import{t as c}from"./WikiPage-BoHNewCX.js";var l={key:1},u={__name:`DocPage`,props:{filename:String},setup(u){let d=u,f=a(null);function p(e,t){let n=new DOMParser().parseFromString(e,`text/html`).body,r=n.querySelector(`:scope > article`)||n,i=r.querySelector(`h1`),a=i?.textContent.trim()||t.split(`/`).pop().replace(/[-_]/g,` `);i?.remove();let o=[...r.querySelectorAll(`h2[id], h3[id], h4[id]`)].map(e=>({level:Number(e.tagName[1]),id:e.id,text:e.textContent.trim()})),s=[{title:`Documentation`}];return t.startsWith(`resources/`)&&s.push({title:`Resource types`}),{title:a,html:r.innerHTML,toc:o.length>=2?o:[],breadcrumb:s}}async function m(){let e=await s(d.filename);f.value=e?p(e,d.filename):{title:`Not found`,html:`<p>Documentation not found.</p>`,toc:[],breadcrumb:[{title:`Documentation`}]},o(f.value.title)}return i(()=>d.filename,m,{immediate:!0}),(i,a)=>f.value?(t(),r(c,{key:0,title:f.value.title,html:f.value.html,breadcrumb:f.value.breadcrumb,toc:f.value.toc},null,8,[`title`,`html`,`breadcrumb`,`toc`])):(t(),e(`article`,l,[...a[0]||=[n(`p`,null,`Loading...`,-1)]]))}};export{u as default};
|