archsight 0.4.3 → 0.5.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/Dockerfile +4 -0
- data/docs/configuration.md +5 -0
- data/docs/diagram.md +5 -0
- data/docs/index.md.erb +1 -0
- data/docs/pdf-export.md +118 -0
- data/lib/archsight/analysis/typst_renderer.rb +25 -78
- data/lib/archsight/cli.rb +37 -0
- data/lib/archsight/diagram/graph/attributes.rb +3 -1
- data/lib/archsight/diagram/graph/node.rb +18 -1
- data/lib/archsight/diagram/layout/expander.rb +75 -3
- data/lib/archsight/diagram/layout/rank_arranger.rb +3 -1
- data/lib/archsight/markdown.rb +17 -1
- data/lib/archsight/pdf/cache.rb +41 -0
- data/lib/archsight/pdf/compiler.rb +69 -0
- data/lib/archsight/pdf/dependency_graph.rb +127 -0
- data/lib/archsight/pdf/document.rb +227 -0
- data/lib/archsight/pdf/embeds.rb +134 -0
- data/lib/archsight/pdf/images.rb +94 -0
- data/lib/archsight/pdf/markdown.rb +217 -0
- data/lib/archsight/pdf/remote_image.rb +122 -0
- data/lib/archsight/pdf/resource_sheet.rb +129 -0
- data/lib/archsight/pdf/sample_document.rb +67 -0
- data/lib/archsight/pdf/tables.rb +72 -0
- data/lib/archsight/pdf/theme.rb +125 -0
- data/lib/archsight/pdf/typst/archsight.typ +152 -0
- data/lib/archsight/pdf/typst.rb +45 -0
- data/lib/archsight/pdf.rb +30 -0
- data/lib/archsight/resources/config.rb +147 -0
- data/lib/archsight/version.rb +1 -1
- data/lib/archsight/web/api/openapi/spec.yaml +230 -0
- data/lib/archsight/web/api/pdf_helpers.rb +46 -0
- data/lib/archsight/web/api/routes.rb +30 -0
- data/lib/archsight/web/public/vue/DocPage-D3QtnrmO.js +1 -0
- data/lib/archsight/web/public/vue/EditorPage-lZyG6dVt.js +35 -0
- data/lib/archsight/web/public/vue/ErrorPage-BhdYGZJk.js +2 -0
- data/lib/archsight/web/public/vue/GraphView-CoqAjFdR.js +1 -0
- data/lib/archsight/web/public/vue/HomePage-B7SaXVeb.js +2 -0
- data/lib/archsight/web/public/vue/{InstanceRouter-CJSkGdBG.css → InstanceRouter-BCKbW-Wp.css} +1 -1
- data/lib/archsight/web/public/vue/InstanceRouter-DJJn9fhP.js +1 -0
- data/lib/archsight/web/public/vue/KindList-UqMajqbf.js +1 -0
- data/lib/archsight/web/public/vue/PageView-CirIXjW6.js +1 -0
- data/lib/archsight/web/public/vue/QueryError-BIJH6gQC.js +1 -0
- data/lib/archsight/web/public/vue/ResourceList-761vG1Jw.js +2 -0
- data/lib/archsight/web/public/vue/SearchResults-BPHa6yhK.js +1 -0
- data/lib/archsight/web/public/vue/WikiPage-Bi7dzY2h.js +3 -0
- data/lib/archsight/web/public/vue/{WikiPage-TpmM1VAF.css → WikiPage-CuUi4C8v.css} +1 -1
- data/lib/archsight/web/public/vue/{index-DMhBow5t.js → index-BF4zUlWZ.js} +2 -2
- data/lib/archsight/web/public/vue/index-BO59Fbpf.css +1 -0
- data/lib/archsight/web/public/vue.html +2 -2
- metadata +35 -17
- data/lib/archsight/web/public/vue/DocPage-L0GzDFiV.js +0 -1
- data/lib/archsight/web/public/vue/EditorPage-B3iNbh1u.js +0 -35
- data/lib/archsight/web/public/vue/ErrorPage-Lro5vwhy.js +0 -2
- data/lib/archsight/web/public/vue/GraphView-BRKwxa--.js +0 -1
- data/lib/archsight/web/public/vue/HomePage-DKgI1DXr.js +0 -2
- data/lib/archsight/web/public/vue/InstanceRouter-CX6qxVTm.js +0 -1
- data/lib/archsight/web/public/vue/KindList-C556gf23.js +0 -1
- data/lib/archsight/web/public/vue/PageView-DAqHjL1x.js +0 -1
- data/lib/archsight/web/public/vue/QueryError-DvspMrsh.js +0 -1
- data/lib/archsight/web/public/vue/ResourceList-BZOYa68X.js +0 -2
- data/lib/archsight/web/public/vue/SearchResults-DaaOPG3t.js +0 -1
- data/lib/archsight/web/public/vue/WikiPage-Bfx92Iig.js +0 -3
- data/lib/archsight/web/public/vue/index-B_YGrWD8.css +0 -1
|
@@ -374,6 +374,234 @@ paths:
|
|
|
374
374
|
"404":
|
|
375
375
|
description: Unknown colour
|
|
376
376
|
|
|
377
|
+
"/api/v1/kinds/Config/instances/{name}/preview":
|
|
378
|
+
get:
|
|
379
|
+
summary: Preview the look of a PDF Config
|
|
380
|
+
description: A fixed sample document (cover page and a page with headings, list,
|
|
381
|
+
quote, table with status badges and code) in the look of one `Config` of type
|
|
382
|
+
`pdf`, typeset by Typst like every PDF export. Served inline, for showing it
|
|
383
|
+
in a page. Only the Config shapes the result, so a changed colour, font or logo
|
|
384
|
+
is visible at once. The response carries an `ETag` (fingerprint of the document
|
|
385
|
+
and the files it is made of) and answers `304` for a matching `If-None-Match`.
|
|
386
|
+
operationId: getConfigPreview
|
|
387
|
+
tags:
|
|
388
|
+
- PDF
|
|
389
|
+
parameters:
|
|
390
|
+
- name: name
|
|
391
|
+
in: path
|
|
392
|
+
required: true
|
|
393
|
+
description: Name of the Config, e.g. `Config:PDF:default`
|
|
394
|
+
schema:
|
|
395
|
+
type: string
|
|
396
|
+
- name: part
|
|
397
|
+
in: query
|
|
398
|
+
required: false
|
|
399
|
+
description: "`cover` or `page` for a document of just that page (the viewer needs no navigation); without it both pages"
|
|
400
|
+
schema:
|
|
401
|
+
type: string
|
|
402
|
+
enum:
|
|
403
|
+
- cover
|
|
404
|
+
- page
|
|
405
|
+
- name: If-None-Match
|
|
406
|
+
in: header
|
|
407
|
+
required: false
|
|
408
|
+
description: The `ETag` of a copy the client has; a match answers `304`
|
|
409
|
+
schema:
|
|
410
|
+
type: string
|
|
411
|
+
responses:
|
|
412
|
+
'200':
|
|
413
|
+
description: The PDF
|
|
414
|
+
headers:
|
|
415
|
+
ETag:
|
|
416
|
+
schema:
|
|
417
|
+
type: string
|
|
418
|
+
Content-Disposition:
|
|
419
|
+
description: '`inline; filename="preview-<name>.pdf"`'
|
|
420
|
+
schema:
|
|
421
|
+
type: string
|
|
422
|
+
content:
|
|
423
|
+
application/pdf:
|
|
424
|
+
schema:
|
|
425
|
+
type: string
|
|
426
|
+
format: binary
|
|
427
|
+
'304':
|
|
428
|
+
description: The client's copy is current
|
|
429
|
+
'404':
|
|
430
|
+
description: No such Config
|
|
431
|
+
content:
|
|
432
|
+
application/json:
|
|
433
|
+
schema:
|
|
434
|
+
"$ref": "#/components/schemas/Error"
|
|
435
|
+
'422':
|
|
436
|
+
description: The Config is not of type `pdf`, or the sample could not be typeset
|
|
437
|
+
(message of typst)
|
|
438
|
+
content:
|
|
439
|
+
application/json:
|
|
440
|
+
schema:
|
|
441
|
+
"$ref": "#/components/schemas/Error"
|
|
442
|
+
'503':
|
|
443
|
+
description: typst is not installed
|
|
444
|
+
content:
|
|
445
|
+
application/json:
|
|
446
|
+
schema:
|
|
447
|
+
"$ref": "#/components/schemas/Error"
|
|
448
|
+
|
|
449
|
+
"/api/v1/kinds/{kind}/instances/{name}/pdf":
|
|
450
|
+
get:
|
|
451
|
+
summary: Download a resource as PDF
|
|
452
|
+
description: |
|
|
453
|
+
Returns one resource as a PDF document, laid out by Typst (`typst` must be installed, the container image has it).
|
|
454
|
+
|
|
455
|
+
**What it contains**: a page is exported as written (headings, tables, images, `asd` diagrams as vector graphics,
|
|
456
|
+
`[[links]]` as their label); any other resource becomes a generated document with its description,
|
|
457
|
+
properties, relations and its `architecture/diagram`. Tags steer the layout: `pdf:cover`, `pdf:toc`,
|
|
458
|
+
`pdf:landscape`, `pdf:draft`, `pdf:template:<name>` and `version:<x>`.
|
|
459
|
+
|
|
460
|
+
**Look**: colours, fonts, logo and the texts of header and footer come from the `Config` resource of type `pdf` named
|
|
461
|
+
`default` (or the one `template` / the tag names); without one a neutral look is used.
|
|
462
|
+
|
|
463
|
+
The response carries an `ETag` (a fingerprint of everything the PDF is made from, so a changed page, image,
|
|
464
|
+
diagram or template changes it) and answers `304` for a matching `If-None-Match`.
|
|
465
|
+
operationId: getInstancePdf
|
|
466
|
+
tags:
|
|
467
|
+
- PDF
|
|
468
|
+
parameters:
|
|
469
|
+
- "$ref": "#/components/parameters/kind"
|
|
470
|
+
- "$ref": "#/components/parameters/name"
|
|
471
|
+
- name: template
|
|
472
|
+
in: query
|
|
473
|
+
required: false
|
|
474
|
+
description: Name of a `Config` of type `pdf` to use instead of the tag or `default`
|
|
475
|
+
schema:
|
|
476
|
+
type: string
|
|
477
|
+
- name: draft
|
|
478
|
+
in: query
|
|
479
|
+
required: false
|
|
480
|
+
description: "`1` adds the draft watermark"
|
|
481
|
+
schema:
|
|
482
|
+
type: string
|
|
483
|
+
enum:
|
|
484
|
+
- '1'
|
|
485
|
+
- name: If-None-Match
|
|
486
|
+
in: header
|
|
487
|
+
required: false
|
|
488
|
+
description: The `ETag` of a copy the client has; a match answers `304`
|
|
489
|
+
schema:
|
|
490
|
+
type: string
|
|
491
|
+
responses:
|
|
492
|
+
'200':
|
|
493
|
+
description: The PDF
|
|
494
|
+
headers:
|
|
495
|
+
ETag:
|
|
496
|
+
schema:
|
|
497
|
+
type: string
|
|
498
|
+
Content-Disposition:
|
|
499
|
+
description: '`attachment; filename="<name>.pdf"`'
|
|
500
|
+
schema:
|
|
501
|
+
type: string
|
|
502
|
+
content:
|
|
503
|
+
application/pdf:
|
|
504
|
+
schema:
|
|
505
|
+
type: string
|
|
506
|
+
format: binary
|
|
507
|
+
'304':
|
|
508
|
+
description: The client's copy is current
|
|
509
|
+
'404':
|
|
510
|
+
description: Not found
|
|
511
|
+
content:
|
|
512
|
+
application/json:
|
|
513
|
+
schema:
|
|
514
|
+
"$ref": "#/components/schemas/Error"
|
|
515
|
+
'422':
|
|
516
|
+
description: The document could not be typeset (message of typst)
|
|
517
|
+
content:
|
|
518
|
+
application/json:
|
|
519
|
+
schema:
|
|
520
|
+
"$ref": "#/components/schemas/Error"
|
|
521
|
+
'503':
|
|
522
|
+
description: typst is not installed
|
|
523
|
+
content:
|
|
524
|
+
application/json:
|
|
525
|
+
schema:
|
|
526
|
+
"$ref": "#/components/schemas/Error"
|
|
527
|
+
"/api/v1/pages/{name}/pdf":
|
|
528
|
+
get:
|
|
529
|
+
summary: Download a page as PDF
|
|
530
|
+
description: |
|
|
531
|
+
Returns one page as a PDF document, laid out by Typst (`typst` must be installed, the container image has it).
|
|
532
|
+
|
|
533
|
+
**What it contains**: a page is exported as written (headings, tables, images, `asd` diagrams as vector graphics,
|
|
534
|
+
`[[links]]` as their label); any other resource becomes a generated document with its description,
|
|
535
|
+
properties, relations and its `architecture/diagram`. Tags steer the layout: `pdf:cover`, `pdf:toc`,
|
|
536
|
+
`pdf:landscape`, `pdf:draft`, `pdf:template:<name>` and `version:<x>`.
|
|
537
|
+
|
|
538
|
+
**Look**: colours, fonts, logo and the texts of header and footer come from the `Config` resource of type `pdf` named
|
|
539
|
+
`default` (or the one `template` / the tag names); without one a neutral look is used.
|
|
540
|
+
|
|
541
|
+
The response carries an `ETag` (a fingerprint of everything the PDF is made from, so a changed page, image,
|
|
542
|
+
diagram or template changes it) and answers `304` for a matching `If-None-Match`.
|
|
543
|
+
operationId: getPagePdf
|
|
544
|
+
tags:
|
|
545
|
+
- PDF
|
|
546
|
+
parameters:
|
|
547
|
+
- "$ref": "#/components/parameters/name"
|
|
548
|
+
- name: template
|
|
549
|
+
in: query
|
|
550
|
+
required: false
|
|
551
|
+
description: Name of a `Config` of type `pdf` to use instead of the tag or `default`
|
|
552
|
+
schema:
|
|
553
|
+
type: string
|
|
554
|
+
- name: draft
|
|
555
|
+
in: query
|
|
556
|
+
required: false
|
|
557
|
+
description: "`1` adds the draft watermark"
|
|
558
|
+
schema:
|
|
559
|
+
type: string
|
|
560
|
+
enum:
|
|
561
|
+
- '1'
|
|
562
|
+
- name: If-None-Match
|
|
563
|
+
in: header
|
|
564
|
+
required: false
|
|
565
|
+
description: The `ETag` of a copy the client has; a match answers `304`
|
|
566
|
+
schema:
|
|
567
|
+
type: string
|
|
568
|
+
responses:
|
|
569
|
+
'200':
|
|
570
|
+
description: The PDF
|
|
571
|
+
headers:
|
|
572
|
+
ETag:
|
|
573
|
+
schema:
|
|
574
|
+
type: string
|
|
575
|
+
Content-Disposition:
|
|
576
|
+
description: '`attachment; filename="<name>.pdf"`'
|
|
577
|
+
schema:
|
|
578
|
+
type: string
|
|
579
|
+
content:
|
|
580
|
+
application/pdf:
|
|
581
|
+
schema:
|
|
582
|
+
type: string
|
|
583
|
+
format: binary
|
|
584
|
+
'304':
|
|
585
|
+
description: The client's copy is current
|
|
586
|
+
'404':
|
|
587
|
+
description: Not found
|
|
588
|
+
content:
|
|
589
|
+
application/json:
|
|
590
|
+
schema:
|
|
591
|
+
"$ref": "#/components/schemas/Error"
|
|
592
|
+
'422':
|
|
593
|
+
description: The document could not be typeset (message of typst)
|
|
594
|
+
content:
|
|
595
|
+
application/json:
|
|
596
|
+
schema:
|
|
597
|
+
"$ref": "#/components/schemas/Error"
|
|
598
|
+
'503':
|
|
599
|
+
description: typst is not installed
|
|
600
|
+
content:
|
|
601
|
+
application/json:
|
|
602
|
+
schema:
|
|
603
|
+
"$ref": "#/components/schemas/Error"
|
|
604
|
+
|
|
377
605
|
/api/v1/assets/{path}:
|
|
378
606
|
get:
|
|
379
607
|
summary: Get an asset (image or draw.io diagram)
|
|
@@ -2120,6 +2348,8 @@ tags:
|
|
|
2120
2348
|
description: Search and query operations
|
|
2121
2349
|
- name: Pages
|
|
2122
2350
|
description: Wiki pages (markdown with frontmatter), the page tree and the home page
|
|
2351
|
+
- name: PDF
|
|
2352
|
+
description: Pages and resources as PDF documents (Typst)
|
|
2123
2353
|
- name: Assets
|
|
2124
2354
|
description: Images and draw.io diagrams that markdown embeds
|
|
2125
2355
|
- name: Macros
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../../pdf"
|
|
4
|
+
require_relative "../../pdf/cache"
|
|
5
|
+
require_relative "../../pdf/sample_document"
|
|
6
|
+
|
|
7
|
+
module Archsight; end
|
|
8
|
+
module Archsight::Web; end
|
|
9
|
+
module Archsight::Web::API; end
|
|
10
|
+
|
|
11
|
+
# Download of a page or resource as PDF
|
|
12
|
+
module Archsight::Web::API::PdfHelpers
|
|
13
|
+
CACHE = Archsight::Pdf::Cache.new
|
|
14
|
+
COMPILER = Archsight::Pdf::Compiler.new
|
|
15
|
+
|
|
16
|
+
# Sends the PDF of `resource`. The ETag is the fingerprint of everything the PDF is made from, so a client (and
|
|
17
|
+
# the server's cache) keeps it exactly as long as the page, its images, diagrams and the template are unchanged.
|
|
18
|
+
# Query: `template` (name of a pdf Config), `draft=1` (watermark).
|
|
19
|
+
def serve_pdf(resource)
|
|
20
|
+
pdf_response do
|
|
21
|
+
Archsight::Pdf.document(db, resource, compiler: COMPILER, template: params[:template].to_s.empty? ? nil : params[:template],
|
|
22
|
+
draft: params[:draft] == "1")
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Sends the sample document in the look of a pdf Config, shown in the page instead of downloaded
|
|
27
|
+
def serve_pdf_preview(config)
|
|
28
|
+
pdf_response("inline") { Archsight::Pdf::SampleDocument.new(db, config, part: params[:part], pdf_images: COMPILER.pdf_images?) }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Typesets the document the block builds and sends it; typst problems are answered as JSON errors
|
|
32
|
+
def pdf_response(disposition = "attachment")
|
|
33
|
+
document = yield
|
|
34
|
+
headers "X-Content-Type-Options" => "nosniff"
|
|
35
|
+
cache_control :private, :must_revalidate, max_age: 0
|
|
36
|
+
etag document.fingerprint
|
|
37
|
+
pdf = CACHE.fetch(document.fingerprint) { Archsight::Pdf.compile(document, compiler: COMPILER) }
|
|
38
|
+
content_type "application/pdf"
|
|
39
|
+
headers "Content-Disposition" => %(#{disposition}; filename="#{document.filename}")
|
|
40
|
+
pdf
|
|
41
|
+
rescue Archsight::Pdf::Unavailable => e
|
|
42
|
+
json_error(e.message, status: 503, error_type: "ServiceUnavailable")
|
|
43
|
+
rescue Archsight::Pdf::Error => e
|
|
44
|
+
json_error(e.message, status: 422, error_type: "UnprocessableEntity")
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -6,6 +6,7 @@ require_relative "json_helpers"
|
|
|
6
6
|
require_relative "page_helpers"
|
|
7
7
|
require_relative "requirements_helpers"
|
|
8
8
|
require_relative "analysis_helpers"
|
|
9
|
+
require_relative "pdf_helpers"
|
|
9
10
|
require_relative "../../assets"
|
|
10
11
|
require_relative "../../openapi"
|
|
11
12
|
|
|
@@ -21,6 +22,7 @@ module Archsight::Web::API::Routes
|
|
|
21
22
|
helpers Archsight::Web::API::PageHelpers
|
|
22
23
|
helpers Archsight::Web::API::RequirementsHelpers
|
|
23
24
|
helpers Archsight::Web::API::AnalysisHelpers
|
|
25
|
+
helpers Archsight::Web::API::PdfHelpers
|
|
24
26
|
|
|
25
27
|
# Rendering is CPU work, previews are typed, not pasted
|
|
26
28
|
MAX_DIAGRAM_SOURCE = 100_000
|
|
@@ -79,6 +81,26 @@ module Archsight::Web::API::Routes
|
|
|
79
81
|
.merge(graph_layers: Archsight::GraphvisRenderer.default_graph_layers(instance.class.layer)))
|
|
80
82
|
end
|
|
81
83
|
|
|
84
|
+
# GET /api/v1/kinds/Config/instances/:name/preview - A sample document in the look of a pdf Config (inline PDF)
|
|
85
|
+
get "/api/v1/kinds/Config/instances/:name/preview" do
|
|
86
|
+
config = db.instance_by_kind("Config", params[:name]) || db.instance_by_alias("Config", params[:name])
|
|
87
|
+
json_error("Instance '#{params[:name]}' not found", status: 404, error_type: "NotFound") unless config
|
|
88
|
+
json_error("Config '#{config.name}' is not of type #{Archsight::Pdf::Theme::TYPE}", status: 422, error_type: "UnprocessableEntity") unless config.annotations["config/type"].to_s.casecmp?(Archsight::Pdf::Theme::TYPE)
|
|
89
|
+
|
|
90
|
+
serve_pdf_preview(config)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# GET /api/v1/kinds/:kind/instances/:name/pdf - The resource as PDF document (Typst), see Archsight::Pdf
|
|
94
|
+
get "/api/v1/kinds/:kind/instances/:name/pdf" do
|
|
95
|
+
klass = Archsight::Resources[params[:kind]]
|
|
96
|
+
json_error("Kind '#{params[:kind]}' not found", status: 404, error_type: "NotFound") unless klass
|
|
97
|
+
|
|
98
|
+
instance = db.instance_by_kind(params[:kind], params[:name]) || db.instance_by_alias(params[:kind], params[:name])
|
|
99
|
+
json_error("Instance '#{params[:name]}' not found", status: 404, error_type: "NotFound") unless instance
|
|
100
|
+
|
|
101
|
+
serve_pdf(instance)
|
|
102
|
+
end
|
|
103
|
+
|
|
82
104
|
# GET /api/v1/pages - Page tree built from PageMenu resources, page tags and filters and the home page
|
|
83
105
|
# (shown at `/`; it is not in the tree unless a menu contains it)
|
|
84
106
|
get "/api/v1/pages" do
|
|
@@ -95,6 +117,14 @@ module Archsight::Web::API::Routes
|
|
|
95
117
|
json_response(build_page_response(page))
|
|
96
118
|
end
|
|
97
119
|
|
|
120
|
+
# GET /api/v1/pages/:name/pdf - The page as PDF document (Typst), see Archsight::Pdf
|
|
121
|
+
get "/api/v1/pages/:name/pdf" do
|
|
122
|
+
page = db.instance_by_kind("Page", params[:name])
|
|
123
|
+
json_error("Page '#{params[:name]}' not found", status: 404, error_type: "NotFound") unless page
|
|
124
|
+
|
|
125
|
+
serve_pdf(page)
|
|
126
|
+
end
|
|
127
|
+
|
|
98
128
|
# GET /api/v1/search - Search with query language
|
|
99
129
|
get "/api/v1/search" do
|
|
100
130
|
query = params[:q]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{B as e,L as t,R as n,X as r,it as i,p as a,t as o,tt as s}from"./index-BF4zUlWZ.js";import{t as c}from"./WikiPage-Bi7dzY2h.js";var l={key:1},u={__name:`DocPage`,props:{filename:String},setup(u){let d=u,f=i(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 a(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 s(()=>d.filename,m,{immediate:!0}),(i,a)=>f.value?(r(),n(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`])):(r(),e(`article`,l,[...a[0]||=[t(`p`,null,`Loading...`,-1)]]))}};export{u as default};
|