collabmd 0.1.44 → 0.1.46
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.
- package/README.md +39 -19
- package/bin/collabmd.js +27 -1
- package/dist/client/assets/CodeMirrorEditor-UCMRAMCV-CYM5nxUi.js +1 -0
- package/dist/client/assets/browser-utils--H_DkyEF.js +1 -0
- package/dist/client/assets/chunk-ERSWUTIN-hHdvnhaY.js +41 -0
- package/dist/client/assets/{chunk-CZQZEIFA-DT3N9fo7.js → chunk-YGJVY4SA-CjSe7Bx7.js} +2 -2
- package/dist/client/assets/comment-thread-store-CdcwrObc.js +1 -0
- package/dist/client/assets/comment-threads-9J6Em-_y.js +4 -0
- package/dist/client/assets/comment-ui-shared-BC4pt4w8.js +7 -0
- package/dist/client/assets/dist-B5HTH2BO.js +1 -0
- package/dist/client/assets/{dist-DhLvC8DS.js → dist-B5Jf1SLZ.js} +2 -2
- package/dist/client/assets/{dist-CnL7Y2sM.js → dist-BDt3rz7l.js} +1 -1
- package/dist/client/assets/dist-BEwK4csK.js +1 -0
- package/dist/client/assets/dist-BKW4PALF.js +1 -0
- package/dist/client/assets/dist-BWcHHOx-.js +1 -0
- package/dist/client/assets/{dist-CYZmbokb.js → dist-BalScOwZ.js} +9 -9
- package/dist/client/assets/dist-Bf8f4HmM.js +6 -0
- package/dist/client/assets/dist-BjHJDtyU.js +1 -0
- package/dist/client/assets/dist-Bm6pf9Bl.js +1 -0
- package/dist/client/assets/dist-BoVBdSjk.js +1 -0
- package/dist/client/assets/dist-CC5IrQMG.js +1 -0
- package/dist/client/assets/{dist-C11hHqv_.js → dist-CCP_AKPG.js} +12 -12
- package/dist/client/assets/dist-CZgOmxK6.js +1 -0
- package/dist/client/assets/{dist-D2AQ-76g.js → dist-Cqhv5LAk.js} +1 -1
- package/dist/client/assets/{dist-MvcV4190.js → dist-D-Z6FLem.js} +1 -1
- package/dist/client/assets/dist-DLMiIsNC.js +11 -0
- package/dist/client/assets/{dist-3bgCp7iY.js → dist-DZKu9Cs8.js} +1 -1
- package/dist/client/assets/dist-DaYdhcVs.js +1 -0
- package/dist/client/assets/dist-FWJsgGYI.js +1 -0
- package/dist/client/assets/dist-Kh2COra_.js +1 -0
- package/dist/client/assets/{dist-JYEDRrPT.js → dist-PDZ3bSqm.js} +1 -1
- package/dist/client/assets/{dist-Drp8uu5J.js → dist-TjMh8n1u.js} +1 -1
- package/dist/client/assets/{dist-DGb27Dl6.js → dist-dtAdgL39.js} +1 -1
- package/dist/client/assets/dist-jv4WdPnK.js +9 -0
- package/dist/client/assets/{dist-DK5Gs2wa.js → dist-rGBmqxC7.js} +1 -1
- package/dist/client/assets/{dist-DCzuX1AF.js → dist-shrl6K_0.js} +1 -1
- package/dist/client/assets/dist-tOaegDYS2.js +1 -0
- package/dist/client/assets/dist-ule2n6ak.js +1 -0
- package/dist/client/assets/dist-xElaxbia.js +1 -0
- package/dist/client/assets/drawio-editor-FzY1cVw8.js +9 -0
- package/dist/client/assets/drawioEditor-BjiKJqlc.js +2 -0
- package/dist/client/assets/editor-session-Cm9ekeNo.js +54 -0
- package/dist/client/assets/embedded-editor-base-CwTkk911.css +1 -0
- package/dist/client/assets/{en-GADW4C6J-DQ6zyCEM.js → en-7NFCYGKX-BrgYZAEe.js} +1 -1
- package/dist/client/assets/{preview-render-profile-BZzGSg6K.js → es-DXGV3RHd.js} +13 -13
- package/dist/client/assets/excalidraw-editor-B46zsTFI.js +9 -0
- package/dist/client/assets/excalidraw-editor-Bt7gMSoh.css +1 -0
- package/dist/client/assets/excalidraw-scene-BOben2gr.js +1 -0
- package/dist/client/assets/excalidrawEditor-CT2pHq7e.js +2 -0
- package/dist/client/assets/export-page-A7NHawJY.js +39 -0
- package/dist/client/assets/exportDocument-B2L8fe34.css +1 -0
- package/dist/client/assets/exportDocument-BaqcOAAW.js +2 -0
- package/dist/client/assets/file-icon-svg-CQAjlWjK.js +1 -0
- package/dist/client/assets/file-kind-BbqgGzpc.js +1 -0
- package/dist/client/assets/image-QXRYHUNP-SWEV8H0J.js +1 -0
- package/dist/client/assets/index-ClbjMBVt.js +2 -0
- package/dist/client/assets/index-Pum8ET-5.css +1 -0
- package/dist/client/assets/main-B3uPyqic.js +893 -0
- package/dist/client/assets/modulepreload-polyfill-P2Xu9kJm.js +1 -0
- package/dist/client/assets/pdf-BL9Pr2D5.js +54 -0
- package/dist/client/assets/pdf.worker-CLesOks4.mjs +64857 -0
- package/dist/client/assets/pdf_viewer-FVkkThnz.js +551 -0
- package/dist/client/assets/preview-diagram-utils-txBCoW8d.js +1 -0
- package/dist/client/assets/{preview-render-compiler-BSaQO_p3.js → preview-render-compiler-BD-XhkS2.js} +2 -2
- package/dist/client/assets/preview-render-compiler-BKedaMxx.js +1 -0
- package/dist/client/assets/preview-render-profile-CE-5rVTC.js +1 -0
- package/dist/client/assets/{preview-render-worker-B42LWvrD.js → preview-render-worker-CiPqc9n6.js} +20 -20
- package/dist/client/assets/prod-Dy20X7eT.js +1 -0
- package/dist/client/assets/prod-hnwh7wRM.js +177 -0
- package/dist/client/assets/quick-switcher-controller-fqOYR7qR.js +12 -0
- package/dist/client/assets/runtime-config-BLrEKVO1.js +1 -0
- package/dist/client/assets/vault-api-client-_LpV1aIn.js +6 -0
- package/dist/client/assets/{yjs-provider-reset-guard-Cox4nxwu.js → yjs-provider-reset-guard-DE0vINDP.js} +1 -1
- package/dist/client/drawio-editor.html +3 -2
- package/dist/client/excalidraw-editor.html +3 -2
- package/dist/client/export-document.html +4 -3
- package/dist/client/index.html +109 -27
- package/docker-compose.yml +42 -0
- package/package.json +26 -15
- package/scripts/local-structurizr-compose.mjs +101 -0
- package/src/client/app/drawio-editor-entry.js +0 -3
- package/src/client/app/drawio-editor.html +1 -0
- package/src/client/app/excalidraw-editor-entry.js +0 -3
- package/src/client/app/excalidraw-editor.html +1 -0
- package/src/client/app/export-document-entry.js +0 -3
- package/src/client/app/export-document.html +1 -0
- package/src/client/app/index.html +106 -24
- package/src/client/app/main-entry.js +0 -5
- package/src/client/application/app-shell/chat-feature.js +180 -124
- package/src/client/application/app-shell/comments-feature.js +20 -11
- package/src/client/application/app-shell/git-feature.js +16 -9
- package/src/client/application/app-shell/presence-feature.js +18 -11
- package/src/client/application/app-shell/ui-feature-shell.js +78 -17
- package/src/client/application/app-shell/ui-feature-sidebar.js +74 -1
- package/src/client/application/app-shell/ui-feature-tab-activity.js +2 -2
- package/src/client/application/app-shell/ui-feature-toolbar.js +2 -52
- package/src/client/application/app-shell/workspace-feature.js +27 -84
- package/src/client/application/app-shell-elements.js +9 -1
- package/src/client/application/diagram-chrome.js +161 -166
- package/src/client/application/diagram-preview-export.js +7 -34
- package/src/client/application/diagram-preview-hydrator.js +1 -19
- package/src/client/application/markdown-frontmatter.js +0 -2
- package/src/client/application/mermaid-preview-hydrator.js +1 -14
- package/src/client/application/pdf-preview-controller.js +992 -0
- package/src/client/application/plantuml-preview-hydrator.js +0 -10
- package/src/client/application/preview-diagram-utils.js +31 -2
- package/src/client/application/preview-render-compiler.js +2 -1
- package/src/client/application/preview-renderer.js +2 -2
- package/src/client/application/quick-switcher-loader.js +3 -1
- package/src/client/application/structurizr-preview-controller.js +395 -0
- package/src/client/application/workspace-coordinator.js +25 -3
- package/src/client/application/workspace-preview-controller.js +91 -5
- package/src/client/bootstrap/collabmd-app-shell.js +155 -43
- package/src/client/browser-utils.js +44 -0
- package/src/client/domain/excalidraw-collaboration.js +0 -2
- package/src/client/domain/room.js +38 -0
- package/src/client/domain/runtime-paths.js +26 -5
- package/src/client/domain/structurizr-language.js +99 -0
- package/src/client/domain/vault-paths.js +48 -0
- package/src/client/excalidraw-editor.js +833 -51
- package/src/client/export/export-pipeline.js +6 -34
- package/src/client/infrastructure/auth-client.js +4 -10
- package/src/client/infrastructure/browser-notification-port.js +33 -20
- package/src/client/infrastructure/browser-preferences-port.js +46 -9
- package/src/client/infrastructure/comment-thread-store.js +34 -13
- package/src/client/infrastructure/editor-session.js +10 -0
- package/src/client/infrastructure/editor-view-adapter.js +133 -5
- package/src/client/infrastructure/excalidraw-room-client.js +103 -14
- package/src/client/infrastructure/git-api-client.js +5 -0
- package/src/client/infrastructure/lobby-presence.js +1 -0
- package/src/client/infrastructure/vault-api-client.js +51 -0
- package/src/client/infrastructure/workspace-sync-client.js +13 -1
- package/src/client/presentation/comment-overview-controller.js +18 -53
- package/src/client/presentation/comment-ui/comment-ui-card.js +1 -12
- package/src/client/presentation/comment-ui/comment-ui-layout.js +242 -219
- package/src/client/presentation/comment-ui/comment-ui-render.js +32 -45
- package/src/client/presentation/comment-ui/comment-ui-shared.js +68 -13
- package/src/client/presentation/comment-ui-controller.js +5 -1
- package/src/client/presentation/drawio-embed-controller.js +9 -102
- package/src/client/presentation/drawio-viewer.js +118 -0
- package/src/client/presentation/excalidraw-embed-controller.js +74 -8
- package/src/client/presentation/file-action-controller.js +134 -0
- package/src/client/presentation/file-explorer-controller.js +33 -3
- package/src/client/presentation/file-explorer-view.js +59 -34
- package/src/client/presentation/file-icon-svg.js +40 -0
- package/src/client/presentation/file-tree-state.js +12 -4
- package/src/client/presentation/git-diff-view-controller.js +731 -3
- package/src/client/presentation/outline-controller.js +86 -0
- package/src/client/presentation/quick-switcher-controller.js +257 -74
- package/src/client/presentation/quick-switcher-text-search.js +3 -3
- package/src/client/presentation/toast-controller.js +3 -0
- package/src/client/styles/components/feedback.css +6 -0
- package/src/client/styles/components/navigation.css +11 -1
- package/src/client/styles/features/collaboration-chat.css +49 -53
- package/src/client/styles/features/collaboration-presence.css +9 -7
- package/src/client/styles/features/comment-card.css +25 -11
- package/src/client/styles/features/comment-overlays.css +0 -4
- package/src/client/styles/features/comment-overview.css +44 -21
- package/src/client/styles/features/comments-drawer.css +2 -100
- package/src/client/styles/features/diagram-preview.css +81 -18
- package/src/client/styles/features/diff-special.css +309 -0
- package/src/client/styles/features/embedded-preview.css +8 -33
- package/src/client/styles/features/quick-switcher.css +8 -0
- package/src/client/styles/foundation/themes.css +6 -0
- package/src/client/styles/foundation/tokens.css +1 -0
- package/src/client/styles/layout/editor-page.css +40 -0
- package/src/client/styles/layout/responsive.css +31 -1
- package/src/client/styles/layout/shell.css +383 -7
- package/src/client/styles/layout/sidebar.css +47 -15
- package/src/client/styles/layout/view-modes.css +1 -0
- package/src/client/styles/overrides/codemirror.css +217 -15
- package/src/client/styles/style.css +1 -0
- package/src/client/styles/surfaces/excalidraw-editor.css +294 -0
- package/src/domain/comment-threads.js +63 -5
- package/src/domain/excalidraw-room-codec.js +6 -4
- package/src/domain/file-kind.js +35 -3
- package/src/server/application/workspace-reconciliation.js +1 -1
- package/src/server/config/env.js +79 -0
- package/src/server/create-app-server.js +14 -3
- package/src/server/domain/bases/base-definition.js +1 -1
- package/src/server/domain/bases/base-expression-runtime.js +1 -4
- package/src/server/domain/bases/base-index-snapshot-store.js +1 -4
- package/src/server/domain/bases/base-query-service.js +1 -77
- package/src/server/domain/bases/base-transform.js +1 -4
- package/src/server/domain/collaboration/collaboration-room.js +55 -21
- package/src/server/domain/comment-overview.js +25 -8
- package/src/server/domain/docx-exporter.js +24 -33
- package/src/server/domain/ripgrep-search-service.js +7 -1
- package/src/server/domain/workspace-state.js +32 -11
- package/src/server/infrastructure/git/diff-service.js +29 -13
- package/src/server/infrastructure/git/git-service.js +61 -10
- package/src/server/infrastructure/git/history-service.js +96 -29
- package/src/server/infrastructure/git/image-mime.js +14 -0
- package/src/server/infrastructure/git/path-utils.js +1 -1
- package/src/server/infrastructure/git/responses.js +0 -95
- package/src/server/infrastructure/git/untracked-files.js +28 -1
- package/src/server/infrastructure/github/github-app-client.js +22 -15
- package/src/server/infrastructure/http/create-git-api-query-handler.js +31 -1
- package/src/server/infrastructure/http/create-request-handler.js +18 -31
- package/src/server/infrastructure/http/create-static-handler.js +5 -2
- package/src/server/infrastructure/http/create-structurizr-api-handler.js +145 -0
- package/src/server/infrastructure/http/create-vault-api-command-handler.js +70 -8
- package/src/server/infrastructure/http/create-vault-api-query-handler.js +51 -3
- package/src/server/infrastructure/http/http-errors.js +7 -1
- package/src/server/infrastructure/http/http-request-helpers.js +22 -0
- package/src/server/infrastructure/persistence/path-utils.js +1 -1
- package/src/server/infrastructure/persistence/vault-file-store.js +3 -0
- package/src/server/infrastructure/structurizr/structurizr-embed.css +43 -0
- package/src/server/infrastructure/structurizr/structurizr-workspace-service.js +374 -0
- package/src/server/infrastructure/websocket/attach-collaboration-gateway.js +4 -22
- package/dist/client/assets/CodeMirrorEditor-UCMRAMCV-CbSISC1w.js +0 -1
- package/dist/client/assets/bases-preview-controller-2pLHk0uk.js +0 -143
- package/dist/client/assets/browser-utils-CKtI_rZl.js +0 -1
- package/dist/client/assets/button-BCEiw4Rw.js +0 -1
- package/dist/client/assets/chunk-AXR3VHVW-0GTk_evH.js +0 -41
- package/dist/client/assets/comment-threads-D-iKphIp.js +0 -4
- package/dist/client/assets/diagram-action-icons-aa_KOv9h.js +0 -36
- package/dist/client/assets/dist-BH87JoHx.js +0 -11
- package/dist/client/assets/dist-BIkPRZO7.js +0 -6
- package/dist/client/assets/dist-BqCsFpx4.js +0 -1
- package/dist/client/assets/dist-C2JHCt8U.js +0 -1
- package/dist/client/assets/dist-CZjTtmTu.js +0 -1
- package/dist/client/assets/dist-Cig4Ov_X.js +0 -1
- package/dist/client/assets/dist-CqQEC8gR.js +0 -1
- package/dist/client/assets/dist-D4Rzqod1.js +0 -1
- package/dist/client/assets/dist-D5sn-mwk.js +0 -9
- package/dist/client/assets/dist-D7G-n87v.js +0 -1
- package/dist/client/assets/dist-DRqOrNgN.js +0 -1
- package/dist/client/assets/dist-DetkMS_4.js +0 -1
- package/dist/client/assets/dist-Dp6FVkQ1.js +0 -1
- package/dist/client/assets/dist-DtbjNB28.js +0 -1
- package/dist/client/assets/dist-DyrYcvpo2.js +0 -1
- package/dist/client/assets/dist-GrygD2zE.js +0 -1
- package/dist/client/assets/dist-HmEpWUow.js +0 -1
- package/dist/client/assets/dist-RTa81Km7.js +0 -1
- package/dist/client/assets/drawio-editor-DDvFoarP.js +0 -9
- package/dist/client/assets/drawio-embed-controller-BD1GTRwn.js +0 -1
- package/dist/client/assets/drawioEditor-Bu5grlH5.js +0 -2
- package/dist/client/assets/editor-session-DGlpiAsK.js +0 -16
- package/dist/client/assets/embedded-editor-base-C9roKYpW.css +0 -1
- package/dist/client/assets/excalidraw-editor-BHu6k8d4.js +0 -9
- package/dist/client/assets/excalidraw-editor-Cr_184EF.css +0 -1
- package/dist/client/assets/excalidraw-embed-controller-y2fenN_g.js +0 -1
- package/dist/client/assets/excalidraw-embed-reconciler-DGiagExg.js +0 -1
- package/dist/client/assets/excalidraw-scene-BvsQ6mLP.js +0 -176
- package/dist/client/assets/excalidrawEditor-4vFE--Uw.js +0 -2
- package/dist/client/assets/export-page-Cby8JzPO.js +0 -39
- package/dist/client/assets/exportDocument-C9v-bc7I.css +0 -1
- package/dist/client/assets/exportDocument-CRHCfsdo.js +0 -2
- package/dist/client/assets/file-history-view-controller-BDjEV9xJ.js +0 -112
- package/dist/client/assets/file-kind-BKPOIRPE.js +0 -1
- package/dist/client/assets/git-diff-view-controller-DgdM1aqb.js +0 -150
- package/dist/client/assets/git-panel-controller-BDTR2HVp.js +0 -207
- package/dist/client/assets/image-XGD7JQR6-XDUWHRpO.js +0 -1
- package/dist/client/assets/index-7xOyXDhP.css +0 -1
- package/dist/client/assets/index-Bz1KuQ6y.js +0 -2
- package/dist/client/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
- package/dist/client/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
- package/dist/client/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
- package/dist/client/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
- package/dist/client/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
- package/dist/client/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
- package/dist/client/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
- package/dist/client/assets/jetbrains-mono-cyrillic-400-normal-BEIGL1Tu.woff2 +0 -0
- package/dist/client/assets/jetbrains-mono-cyrillic-400-normal-ugxPyKxw.woff +0 -0
- package/dist/client/assets/jetbrains-mono-greek-400-normal-B9oWc5Lo.woff +0 -0
- package/dist/client/assets/jetbrains-mono-greek-400-normal-C190GLew.woff2 +0 -0
- package/dist/client/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
- package/dist/client/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
- package/dist/client/assets/jetbrains-mono-latin-ext-400-normal-Bc8Ftmh3.woff2 +0 -0
- package/dist/client/assets/jetbrains-mono-latin-ext-400-normal-fXTG6kC5.woff +0 -0
- package/dist/client/assets/jetbrains-mono-vietnamese-400-normal-CqNFfHCs.woff +0 -0
- package/dist/client/assets/main-Ci07m9oP.js +0 -152
- package/dist/client/assets/preview-diagram-utils-n_bbJA9V.js +0 -1
- package/dist/client/assets/preview-render-compiler-csGM5ZFz.js +0 -1
- package/dist/client/assets/quick-switcher-controller-CoiYvllm.js +0 -12
- package/dist/client/assets/room-CDrmIdDt.js +0 -1
- package/dist/client/assets/runtime-config-CDgeuPWN.js +0 -1
- package/dist/client/assets/runtime-config-loader-BHGniHP5.js +0 -1
- package/dist/client/assets/runtime-paths-DvpihCEq.js +0 -1
- package/dist/client/assets/segmented-control-DJrHSz8M.js +0 -1
- package/dist/client/assets/vault-api-client-sLB2bo56.js +0 -1
- package/dist/client/assets/vault-paths-CVkuh0j-.js +0 -5
- package/src/client/bootstrap/lazy-controller-feature.js +0 -433
- package/src/client/infrastructure/backlinks-api-client.js +0 -16
- package/src/client/infrastructure/plantuml-api-client.js +0 -19
- package/src/client/infrastructure/runtime-config-loader.js +0 -56
- package/src/server/domain/collaboration/room-persistence-controller.js +0 -80
- package/src/server/infrastructure/git/command-runner.js +0 -49
- package/src/server/infrastructure/git/errors.js +0 -8
- package/src/server/infrastructure/http/create-esm-proxy-handler.js +0 -130
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { mkdir, readFile, readdir, realpath, rm, stat, utimes, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { basename, dirname, join, resolve } from 'node:path';
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
isStructurizrFilePath,
|
|
7
|
+
isVaultFilePath,
|
|
8
|
+
} from '../../../domain/file-kind.js';
|
|
9
|
+
import { sanitizeVaultPath } from '../persistence/path-utils.js';
|
|
10
|
+
|
|
11
|
+
const MANIFEST_FILE_NAME = '.collabmd-manifest.json';
|
|
12
|
+
const WORKSPACE_DSL_FILE_NAME = 'workspace.dsl';
|
|
13
|
+
const WORKSPACE_JSON_FILE_NAME = 'workspace.json';
|
|
14
|
+
const SIDECAR_TIMEOUT_MS = 15_000;
|
|
15
|
+
|
|
16
|
+
function createServiceError(message, statusCode, code) {
|
|
17
|
+
const error = new Error(message);
|
|
18
|
+
error.statusCode = statusCode;
|
|
19
|
+
error.requestCode = code;
|
|
20
|
+
return error;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function normalizeWorkspaceRootPath(pathValue) {
|
|
24
|
+
const normalized = String(pathValue ?? '').trim().replace(/\\/g, '/');
|
|
25
|
+
if (!normalized || normalized.startsWith('/') || normalized.split('/').some((segment) => !segment || segment === '.' || segment === '..')) {
|
|
26
|
+
return '';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return normalized;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function validateStructurizrDsl(source, { trustedExecutableDsl = false } = {}) {
|
|
33
|
+
if (trustedExecutableDsl) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const text = String(source ?? '');
|
|
38
|
+
if (/^\s*!script\b/im.test(text) || /^\s*!plugin\b/im.test(text)) {
|
|
39
|
+
throw createServiceError(
|
|
40
|
+
'Executable Structurizr DSL is disabled for this workspace.',
|
|
41
|
+
422,
|
|
42
|
+
'STRUCTURIZR_EXECUTABLE_DSL_DISABLED',
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (/^\s*!include\s+<?(?:https?|file):/im.test(text)) {
|
|
47
|
+
throw createServiceError(
|
|
48
|
+
'Remote Structurizr DSL includes are disabled for this workspace.',
|
|
49
|
+
422,
|
|
50
|
+
'STRUCTURIZR_REMOTE_INCLUDE_DISABLED',
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function isMirrorFileAllowed(relativePath) {
|
|
56
|
+
return basename(relativePath) === WORKSPACE_JSON_FILE_NAME || isVaultFilePath(relativePath);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function collectWorkspaceFiles(directoryPath, prefix = '') {
|
|
60
|
+
const files = new Map();
|
|
61
|
+
const entries = (await readdir(directoryPath, { withFileTypes: true }))
|
|
62
|
+
.sort((left, right) => left.name.localeCompare(right.name, undefined, { sensitivity: 'base' }));
|
|
63
|
+
|
|
64
|
+
for (const entry of entries) {
|
|
65
|
+
if (entry.name.startsWith('.') || entry.name === 'node_modules' || entry.name === '.git') {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
70
|
+
const absolutePath = join(directoryPath, entry.name);
|
|
71
|
+
if (entry.isDirectory()) {
|
|
72
|
+
const nested = await collectWorkspaceFiles(absolutePath, relativePath);
|
|
73
|
+
nested.forEach((content, pathValue) => files.set(pathValue, content));
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (!entry.isFile() || !isMirrorFileAllowed(relativePath)) {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
files.set(relativePath, await readFile(absolutePath));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return files;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async function collectMirrorPaths(directoryPath, prefix = '') {
|
|
88
|
+
let entries;
|
|
89
|
+
try {
|
|
90
|
+
entries = await readdir(directoryPath, { withFileTypes: true });
|
|
91
|
+
} catch (error) {
|
|
92
|
+
if (error.code === 'ENOENT') {
|
|
93
|
+
return [];
|
|
94
|
+
}
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const paths = [];
|
|
99
|
+
for (const entry of entries) {
|
|
100
|
+
if (entry.name === '.structurizr') {
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
105
|
+
const absolutePath = join(directoryPath, entry.name);
|
|
106
|
+
if (entry.isDirectory()) {
|
|
107
|
+
paths.push(...await collectMirrorPaths(absolutePath, relativePath));
|
|
108
|
+
} else if (entry.isFile()) {
|
|
109
|
+
paths.push(relativePath);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return paths;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async function readManifest(manifestPath) {
|
|
117
|
+
try {
|
|
118
|
+
const parsed = JSON.parse(await readFile(manifestPath, 'utf8'));
|
|
119
|
+
return Array.isArray(parsed?.paths) ? parsed.paths : [];
|
|
120
|
+
} catch (error) {
|
|
121
|
+
if (error.code === 'ENOENT' || error instanceof SyntaxError) {
|
|
122
|
+
return [];
|
|
123
|
+
}
|
|
124
|
+
throw error;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
async function writeMirrorFiles(mirrorDir, files) {
|
|
129
|
+
await Promise.all(Array.from(files, async ([relativePath, content]) => {
|
|
130
|
+
const targetPath = join(mirrorDir, relativePath);
|
|
131
|
+
await mkdir(dirname(targetPath), { recursive: true });
|
|
132
|
+
await writeFile(targetPath, content);
|
|
133
|
+
}));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async function removeMirrorPaths(mirrorDir, paths) {
|
|
137
|
+
await Promise.all(paths.map((relativePath) => rm(join(mirrorDir, relativePath), {
|
|
138
|
+
force: true,
|
|
139
|
+
recursive: true,
|
|
140
|
+
})));
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
async function snapshotMirror(mirrorDir) {
|
|
144
|
+
const paths = await collectMirrorPaths(mirrorDir);
|
|
145
|
+
const files = new Map();
|
|
146
|
+
await Promise.all(paths.map(async (relativePath) => {
|
|
147
|
+
files.set(relativePath, await readFile(join(mirrorDir, relativePath)));
|
|
148
|
+
}));
|
|
149
|
+
return files;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async function restoreMirror(mirrorDir, snapshot) {
|
|
153
|
+
await removeMirrorPaths(mirrorDir, await collectMirrorPaths(mirrorDir));
|
|
154
|
+
await writeMirrorFiles(mirrorDir, snapshot);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function hashFiles(files) {
|
|
158
|
+
const hash = createHash('sha256');
|
|
159
|
+
Array.from(files.keys()).sort().forEach((pathValue) => {
|
|
160
|
+
hash.update(pathValue);
|
|
161
|
+
hash.update('\0');
|
|
162
|
+
hash.update(files.get(pathValue));
|
|
163
|
+
hash.update('\0');
|
|
164
|
+
});
|
|
165
|
+
return hash.digest('hex');
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export class StructurizrWorkspaceService {
|
|
169
|
+
constructor({
|
|
170
|
+
mirrorDir,
|
|
171
|
+
serverUrl = '',
|
|
172
|
+
trustedExecutableDsl = false,
|
|
173
|
+
vaultDir,
|
|
174
|
+
}) {
|
|
175
|
+
this.mirrorDir = resolve(mirrorDir);
|
|
176
|
+
this.serverUrl = String(serverUrl ?? '').trim().replace(/\/+$/u, '');
|
|
177
|
+
this.trustedExecutableDsl = Boolean(trustedExecutableDsl);
|
|
178
|
+
this.vaultDir = resolve(vaultDir);
|
|
179
|
+
this.syncPromise = Promise.resolve();
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
isEnabled() {
|
|
183
|
+
return Boolean(this.serverUrl);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
isProxyPath(pathname) {
|
|
187
|
+
return this.isEnabled() && (
|
|
188
|
+
pathname === '/workspace/1'
|
|
189
|
+
|| pathname.startsWith('/workspace/1/')
|
|
190
|
+
|| pathname.startsWith('/static/')
|
|
191
|
+
|| pathname === '/api/workspace/1'
|
|
192
|
+
|| pathname.startsWith('/api/workspace/1/')
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
async sync({ content, rootPath }) {
|
|
197
|
+
if (!this.isEnabled()) {
|
|
198
|
+
throw createServiceError('Structurizr renderer is not configured.', 503, 'STRUCTURIZR_NOT_CONFIGURED');
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const run = async () => this.syncWorkspace({ content, rootPath });
|
|
202
|
+
this.syncPromise = this.syncPromise.catch(() => {}).then(run);
|
|
203
|
+
return this.syncPromise;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
async syncWorkspace({ content, rootPath }) {
|
|
207
|
+
const normalizedRootPath = normalizeWorkspaceRootPath(rootPath);
|
|
208
|
+
if (!isStructurizrFilePath(normalizedRootPath)) {
|
|
209
|
+
throw createServiceError('Structurizr previews require a workspace.dsl root file.', 400, 'STRUCTURIZR_ROOT_REQUIRED');
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const rootAbsolutePath = sanitizeVaultPath(this.vaultDir, normalizedRootPath);
|
|
213
|
+
if (!rootAbsolutePath) {
|
|
214
|
+
throw createServiceError('Invalid Structurizr workspace path.', 400, 'STRUCTURIZR_ROOT_INVALID');
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
let rootInfo;
|
|
218
|
+
try {
|
|
219
|
+
rootInfo = await stat(rootAbsolutePath);
|
|
220
|
+
} catch (error) {
|
|
221
|
+
if (error.code === 'ENOENT') {
|
|
222
|
+
throw createServiceError('Structurizr workspace not found.', 404, 'STRUCTURIZR_ROOT_NOT_FOUND');
|
|
223
|
+
}
|
|
224
|
+
throw error;
|
|
225
|
+
}
|
|
226
|
+
if (!rootInfo.isFile()) {
|
|
227
|
+
throw createServiceError('Structurizr workspace root is not a file.', 400, 'STRUCTURIZR_ROOT_INVALID');
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const [vaultRealPath, rootRealPath] = await Promise.all([
|
|
231
|
+
realpath(this.vaultDir),
|
|
232
|
+
realpath(rootAbsolutePath),
|
|
233
|
+
]);
|
|
234
|
+
if (rootRealPath !== vaultRealPath && !rootRealPath.startsWith(`${vaultRealPath}/`)) {
|
|
235
|
+
throw createServiceError('Structurizr workspace must remain inside the vault.', 400, 'STRUCTURIZR_ROOT_INVALID');
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const sourceDirectory = dirname(rootRealPath);
|
|
239
|
+
const files = await collectWorkspaceFiles(sourceDirectory);
|
|
240
|
+
const sourceRootFileName = basename(normalizedRootPath);
|
|
241
|
+
const rootSource = typeof content === 'string'
|
|
242
|
+
? content
|
|
243
|
+
: files.get(sourceRootFileName)?.toString('utf8');
|
|
244
|
+
if (typeof rootSource !== 'string') {
|
|
245
|
+
throw createServiceError('Structurizr workspace source is unavailable.', 400, 'STRUCTURIZR_ROOT_UNREADABLE');
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
files.delete(sourceRootFileName);
|
|
249
|
+
files.set(WORKSPACE_DSL_FILE_NAME, Buffer.from(rootSource, 'utf8'));
|
|
250
|
+
for (const [pathValue, fileContent] of files) {
|
|
251
|
+
if (pathValue.toLowerCase().endsWith('.dsl')) {
|
|
252
|
+
validateStructurizrDsl(fileContent.toString('utf8'), {
|
|
253
|
+
trustedExecutableDsl: this.trustedExecutableDsl,
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
await mkdir(this.mirrorDir, { recursive: true });
|
|
259
|
+
const snapshot = await snapshotMirror(this.mirrorDir);
|
|
260
|
+
const previousManifest = await readManifest(join(this.mirrorDir, MANIFEST_FILE_NAME));
|
|
261
|
+
const sourcePaths = Array.from(files.keys());
|
|
262
|
+
const stalePaths = previousManifest.filter((pathValue) => !files.has(pathValue));
|
|
263
|
+
|
|
264
|
+
try {
|
|
265
|
+
await removeMirrorPaths(this.mirrorDir, stalePaths);
|
|
266
|
+
await writeMirrorFiles(this.mirrorDir, files);
|
|
267
|
+
// Local caches workspace.json; an old mtime makes it parse the DSL without a delete race.
|
|
268
|
+
const workspaceJsonPath = join(this.mirrorDir, WORKSPACE_JSON_FILE_NAME);
|
|
269
|
+
try {
|
|
270
|
+
await utimes(workspaceJsonPath, new Date(0), new Date(0));
|
|
271
|
+
} catch (error) {
|
|
272
|
+
if (error.code !== 'ENOENT') {
|
|
273
|
+
throw error;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
await this.validateMirror();
|
|
277
|
+
if (files.has(WORKSPACE_JSON_FILE_NAME)) {
|
|
278
|
+
await writeMirrorFiles(this.mirrorDir, new Map([
|
|
279
|
+
[WORKSPACE_JSON_FILE_NAME, files.get(WORKSPACE_JSON_FILE_NAME)],
|
|
280
|
+
]));
|
|
281
|
+
}
|
|
282
|
+
await writeFile(
|
|
283
|
+
join(this.mirrorDir, MANIFEST_FILE_NAME),
|
|
284
|
+
`${JSON.stringify({ paths: sourcePaths }, null, 2)}\n`,
|
|
285
|
+
'utf8',
|
|
286
|
+
);
|
|
287
|
+
} catch (error) {
|
|
288
|
+
await restoreMirror(this.mirrorDir, snapshot);
|
|
289
|
+
throw error;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return {
|
|
293
|
+
ok: true,
|
|
294
|
+
rootPath: normalizedRootPath,
|
|
295
|
+
version: hashFiles(files),
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
async validateMirror() {
|
|
300
|
+
for (let attempt = 0; attempt < 8; attempt += 1) {
|
|
301
|
+
let response;
|
|
302
|
+
try {
|
|
303
|
+
response = await fetch(`${this.serverUrl}/api/workspace/1`, {
|
|
304
|
+
headers: { Accept: 'application/json' },
|
|
305
|
+
signal: AbortSignal.timeout(SIDECAR_TIMEOUT_MS),
|
|
306
|
+
});
|
|
307
|
+
} catch (error) {
|
|
308
|
+
throw createServiceError(
|
|
309
|
+
`Structurizr renderer is unavailable: ${error.message}`,
|
|
310
|
+
503,
|
|
311
|
+
'STRUCTURIZR_UNAVAILABLE',
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
const payload = await response.json().catch(() => ({}));
|
|
316
|
+
if (response.ok && payload.success !== false) {
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
const message = String(payload.message || payload.error || `Structurizr renderer returned HTTP ${response.status}`)
|
|
321
|
+
.replace(/^com\.structurizr\.dsl\.StructurizrDslParserException:\s*/u, '');
|
|
322
|
+
const isTransientStartupFailure = response.status >= 500
|
|
323
|
+
&& /(?:No workspace|FileNotFoundException|workspace\.json)/iu.test(message);
|
|
324
|
+
if (isTransientStartupFailure && attempt < 7) {
|
|
325
|
+
await new Promise((resolvePromise) => setTimeout(resolvePromise, 250));
|
|
326
|
+
continue;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
throw createServiceError(
|
|
330
|
+
message,
|
|
331
|
+
response.status >= 400 && response.status < 500 ? 422 : 502,
|
|
332
|
+
response.status >= 400 && response.status < 500
|
|
333
|
+
? 'STRUCTURIZR_DSL_INVALID'
|
|
334
|
+
: 'STRUCTURIZR_VALIDATION_FAILED',
|
|
335
|
+
);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
async proxy(requestUrl, { method = 'GET', headers = {} } = {}) {
|
|
340
|
+
if (!this.isProxyPath(requestUrl.pathname)) {
|
|
341
|
+
return null;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
const upstreamUrl = `${this.serverUrl}${requestUrl.pathname}${requestUrl.search}`;
|
|
345
|
+
let response;
|
|
346
|
+
try {
|
|
347
|
+
const proxyHeaders = {
|
|
348
|
+
Accept: headers.accept || '*/*',
|
|
349
|
+
};
|
|
350
|
+
if (headers.range) {
|
|
351
|
+
proxyHeaders.Range = headers.range;
|
|
352
|
+
}
|
|
353
|
+
response = await fetch(upstreamUrl, {
|
|
354
|
+
headers: proxyHeaders,
|
|
355
|
+
method,
|
|
356
|
+
redirect: 'follow',
|
|
357
|
+
signal: AbortSignal.timeout(SIDECAR_TIMEOUT_MS),
|
|
358
|
+
});
|
|
359
|
+
} catch (error) {
|
|
360
|
+
throw createServiceError(
|
|
361
|
+
`Structurizr renderer is unavailable: ${error.message}`,
|
|
362
|
+
503,
|
|
363
|
+
'STRUCTURIZR_UNAVAILABLE',
|
|
364
|
+
);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
return {
|
|
368
|
+
body: Buffer.from(await response.arrayBuffer()),
|
|
369
|
+
contentType: response.headers.get('content-type') || 'application/octet-stream',
|
|
370
|
+
statusCode: response.status,
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { WebSocketServer } from 'ws';
|
|
2
2
|
|
|
3
3
|
import { normalizeHostedEmail } from '../../domain/hosted-workspace-contract.js';
|
|
4
|
+
import {
|
|
5
|
+
createRequestUrlWithPathname,
|
|
6
|
+
stripBasePath,
|
|
7
|
+
} from '../http/http-request-helpers.js';
|
|
4
8
|
import { ClientSocketSession } from './client-socket-session.js';
|
|
5
9
|
|
|
6
10
|
function rejectUpgrade(socket, statusCode, statusMessage, {
|
|
@@ -25,28 +29,6 @@ function extractRoomName(pathname, wsBasePath) {
|
|
|
25
29
|
return decodeURIComponent(roomSegment || 'default');
|
|
26
30
|
}
|
|
27
31
|
|
|
28
|
-
function stripBasePath(pathname, basePath) {
|
|
29
|
-
if (!basePath) {
|
|
30
|
-
return pathname;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (pathname === basePath) {
|
|
34
|
-
return '/';
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
if (pathname.startsWith(`${basePath}/`)) {
|
|
38
|
-
return pathname.slice(basePath.length) || '/';
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return pathname;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function createRequestUrlWithPathname(requestUrl, pathname) {
|
|
45
|
-
const nextUrl = new URL(requestUrl.toString());
|
|
46
|
-
nextUrl.pathname = pathname || '/';
|
|
47
|
-
return nextUrl;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
32
|
export function attachCollaborationGateway({
|
|
51
33
|
authService,
|
|
52
34
|
basePath = '',
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{i as e}from"./rolldown-runtime-Dd_uD5pT.js";import{A as t,F as n,J as r,L as i,P as a,V as o,X as s,c,lt as l,q as u,st as d,t as f}from"./dist-C11hHqv_.js";import"./chunk-SRAX5OIU-KFQikY-4.js";import{n as p,t as m}from"./jsx-runtime-BpzPEenQ.js";import{n as h,r as g,s as _,t as v}from"./dist-GrygD2zE.js";var y=e(p(),1),b=m(),x=c.define({token(e){return e.match(/^%%.*$/)?`comment`:e.match(/^"(?:[^"\\]|\\.)*"/)?`string`:e.match(/^(flowchart|graph|sequenceDiagram|classDiagram|stateDiagram|erDiagram|gantt|pie|mindmap|journey|gitGraph|timeline|quadrantChart|sankey|xychart)\b/i)||e.match(/^(TB|TD|BT|RL|LR)\b/)||e.match(/^(subgraph|end|participant|actor|loop|alt|else|opt|par|critical|break|rect|note|over|activate|deactivate|title|section|class|style|linkStyle|classDef|click)\b/i)?`keyword`:e.match(/^[-.=<>|ox]+>/)||e.match(/^<[-.=<>|ox]+/)||e.match(/^--+|\.\.+|==+/)?`operator`:e.match(/^[[\](){}|<>]/)?`bracket`:e.match(/^[A-Za-z_][A-Za-z0-9_]*/)?`variableName`:e.match(/^\d+(\.\d+)?/)?`number`:e.match(/^[,:;]/)?`punctuation`:(e.eatSpace()||e.next(),null)}});function S(){return x}var C=i.theme({"&":{backgroundColor:`#1e1e1e`,color:`#d4d4d4`},".cm-content":{caretColor:`#fff`},".cm-cursor":{borderLeftColor:`#fff`},".cm-gutters":{backgroundColor:`#1e1e1e`,color:`#858585`,border:`none`},".cm-activeLineGutter":{backgroundColor:`#2a2a2a`},".cm-activeLine":{backgroundColor:`#2a2a2a`},".cm-errorLine":{backgroundColor:`rgba(255, 0, 0, 0.15)`}},{dark:!0}),w=f.define([{tag:a.keyword,color:`#569cd6`},{tag:a.string,color:`#ce9178`},{tag:a.comment,color:`#6a9955`},{tag:a.number,color:`#b5cea8`},{tag:a.operator,color:`#d4d4d4`},{tag:a.punctuation,color:`#d4d4d4`},{tag:a.variableName,color:`#9cdcfe`},{tag:a.bracket,color:`#ffd700`}]),T=i.theme({"&":{backgroundColor:`#ffffff`,color:`#1e1e1e`},".cm-content":{caretColor:`#000`},".cm-cursor":{borderLeftColor:`#000`},".cm-gutters":{backgroundColor:`#fff`,color:`#999`,border:`none`},".cm-activeLineGutter":{backgroundColor:`#e8e8e8`},".cm-activeLine":{backgroundColor:`#e8e8e8`},".cm-errorLine":{backgroundColor:`rgba(255, 0, 0, 0.1)`}}),E=f.define([{tag:a.keyword,color:`#0000ff`},{tag:a.string,color:`#a31515`},{tag:a.comment,color:`#008000`},{tag:a.number,color:`#098658`},{tag:a.operator,color:`#1e1e1e`},{tag:a.punctuation,color:`#1e1e1e`},{tag:a.variableName,color:`#001080`},{tag:a.bracket,color:`#af00db`}]),D=n.line({class:`cm-errorLine`}),O=(e,t)=>{if(!e||e<1||e>t.lines)return i.decorations.of(n.none);let r=t.line(e);return i.decorations.of(n.set([D.range(r.from)]))},k=e=>e===`dark`?[C,t(w)]:[T,t(E)],A=({value:e,onChange:t,onKeyboardSubmit:n,placeholder:a,theme:c,errorLine:f})=>{let p=(0,y.useRef)(null),m=(0,y.useRef)(null),x=(0,y.useRef)(t),C=(0,y.useRef)(n),w=(0,y.useRef)(new d),T=(0,y.useRef)(new d);return x.current=t,C.current=n,(0,y.useEffect)(()=>{if(!p.current)return;let t=w.current,n=new i({state:l.create({doc:e,extensions:[u.of([{key:`Mod-Enter`,run:()=>(C.current?.(),!0)},{key:`Mod-Shift-z`,run:_,preventDefault:!0}]),i.updateListener.of(e=>{e.docChanged&&x.current(e.state.doc.toString())}),h(),u.of([...v,...g]),r(),i.lineWrapping,t.of(k(c)),T.current.of([]),S(),o({drawRangeCursor:!0}),...a?[s(a)]:[]]}),parent:p.current});return m.current=n,n.focus(),()=>{n.destroy(),m.current=null}},[]),(0,y.useEffect)(()=>{let e=m.current;e&&e.dispatch({effects:w.current.reconfigure(k(c))})},[c]),(0,y.useEffect)(()=>{let e=m.current;e&&e.dispatch({effects:T.current.reconfigure(O(f,e.state.doc))})},[f]),(0,y.useEffect)(()=>{let t=m.current;if(!t)return;let n=t.state.doc.toString();e!==n&&t.dispatch({changes:{from:0,to:n.length,insert:e}})},[e]),(0,b.jsx)(`div`,{ref:p,className:`ttd-dialog-input ttd-dialog-input--codemirror`})};export{A as default};
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
import{c as e}from"./file-kind-BKPOIRPE.js";import{n as t}from"./vault-utils-wdQ0RNR9.js";import{n}from"./runtime-paths-DvpihCEq.js";import{i as r,n as i}from"./browser-utils-CKtI_rZl.js";import{r as a,t as o}from"./button-BCEiw4Rw.js";import{n as s,t as c}from"./segmented-control-DJrHSz8M.js";function l(){return`base-${Math.random().toString(36).slice(2,10)}`}function u(e=``){return/^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/iu.test(String(e??``).trim())}function d(e=``){return/^https?:\/\/.+\.(?:png|jpe?g|webp|gif|svg)(?:[?#].*)?$/iu.test(String(e??``).trim())}function f(e){return Object.prototype.toString.call(e)===`[object Object]`}function p(e=`and`){return{children:[],conjunction:e,type:`group`}}function m(e,t,n){let r=e.image||t.find(e=>[`cover`,`image`].includes(String(e.id??``).toLowerCase()))?.id||null;return r?n.cells[r]??null:null}function h(e){return String(e?.text??``)}function g(e=``){return n(`/attachment?path=${encodeURIComponent(e)}`)}function ee(t={}){if(t?.type===`image`&&t.path)return g(t.path);if(t?.type===`link`){if(t.external&&d(t.url))return t.url;if(t.path&&e(t.path))return g(t.path)}let n=h(t);return d(n)?n:e(n)?g(n):``}function _(e={}){let n=e?.type||`string`;if(n===`empty`)return`<span class="bases-value bases-value-empty">—</span>`;if(n===`boolean`)return`<span class="bases-value bases-value-boolean">${e.value?`True`:`False`}</span>`;if(n===`image`&&e.path)return`<img class="bases-inline-image" src="${t(g(e.path))}" alt="${t(h(e))}">`;if(n===`list`)return`<span class="bases-value-list">${(e.items??[]).map(e=>`<span class="bases-value-pill">${_(e)}</span>`).join(``)}</span>`;if(n===`link`){if(e.external&&e.url)return`<a class="bases-link" href="${t(e.url)}" target="_blank" rel="noopener noreferrer">${t(h(e))}</a>`;if(e.path)return`<button type="button" class="${t(o({variant:`secondary`,size:`compact`,pill:!0,extra:[`bases-link`,`bases-link-button`]}))}" data-base-open-file="${t(e.path)}">${t(h(e))}</button>`}if(n===`file`&&e.path)return`<button type="button" class="${t(o({variant:`secondary`,size:`compact`,pill:!0,extra:[`bases-link`,`bases-link-button`]}))}" data-base-open-file="${t(e.path)}">${t(h(e))}</button>`;let r=h(e);return`<span class="bases-value">${t(r)}</span>`}function v(e,n){let r=n?.cells?.[e.id]??null;return n?.path&&r&&r.type!==`empty`&&(e.id===`file.name`||e.id===`file.basename`)?`<button type="button" class="${t(o({variant:`secondary`,size:`compact`,pill:!0,extra:[`bases-link`,`bases-link-button`]}))}" data-base-open-file="${t(n.path)}">${t(h(r))}</button>`:_(r)}function y(e=[]){return!Array.isArray(e)||e.length===0?``:`<div class="bases-summaries">${e.map(e=>`<div class="bases-summary"><span class="bases-summary-label">${t(e.label)}</span><span class="bases-summary-value">${t(h(e.value))}</span></div>`).join(``)}</div>`}function te(e,n){return n.map(n=>`<section class="bases-group"><header class="bases-group-header"><h3>${t(n.label)}</h3>${y(n.summaries)}</header><div class="bases-table-shell"><table class="bases-table"><thead><tr>${e.map(e=>`<th>${t(e.label)}</th>`).join(``)}</tr></thead><tbody>${(n.rows??[]).map(t=>`<tr>${e.map(e=>`<td>${v(e,t)}</td>`).join(``)}</tr>`).join(``)}</tbody></table></div></section>`).join(``)}function ne(e,n){return n.map(n=>`<section class="bases-group"><header class="bases-group-header"><h3>${t(n.label)}</h3>${y(n.summaries)}</header><ul class="bases-list">${(n.rows??[]).map(n=>`<li class="bases-list-item">${e.map(e=>{let r=n.cells[e.id];return!r||r.type===`empty`?``:`<span class="bases-list-field"><strong>${t(e.label)}:</strong> ${v(e,n)}</span>`}).join(``)}</li>`).join(``)}</ul></section>`).join(``)}function re(e,n,r){return n.map(n=>`<section class="bases-group"><header class="bases-group-header"><h3>${t(n.label)}</h3>${y(n.summaries)}</header><div class="bases-cards">${(n.rows??[]).map(n=>{let i=m(r,e,n),a=h(i),o=``;if(u(a))o=`<div class="bases-card-media bases-card-media-color" style="--bases-card-swatch:${t(a)}"></div>`;else{let e=ee(i);e&&(o=`<img class="bases-card-media" src="${t(e)}" alt="${t(a)}">`)}return`<article class="bases-card">${o}<div class="bases-card-body">${e.map(e=>{let r=n.cells[e.id];return!r||r.type===`empty`?``:`<div class="bases-card-field"><div class="bases-card-label">${t(e.label)}</div><div class="bases-card-value">${v(e,n)}</div></div>`}).join(``)}</div></article>`}).join(``)}</div></section>`).join(``)}function b(e){if(!e.view.supported)return`<div class="bases-unsupported">CollabMD parsed this view but does not render the <code>${t(e.view.type)}</code> layout yet.</div>`;switch(e.view.type){case`cards`:return re(e.columns,e.groups,e.view);case`list`:return ne(e.columns,e.groups);default:return te(e.columns,e.groups)}}function x(e){return(e.views??[]).map(n=>`<button type="button" class="${t(c({active:n.id===e.view.id,extra:`bases-view-tab`}))}" data-base-view="${t(n.id)}">${t(n.name)}</button>`).join(``)}function S(e){return e?.meta??{}}function C(e){return S(e).availableProperties??[]}function w(e){let t=S(e).activeViewConfig?.order;return Array.isArray(t)&&t.length>0?[...t]:Array.isArray(e?.columns)?e.columns.map(e=>e.id).filter(Boolean):[]}function T(e,t=``){return C(e).find(e=>e.id===t)??null}function E(e,t=``){return T(e,t)?.filterOperators??[`is`,`is not`,`contains`,`does not contain`,`is empty`,`is not empty`]}function D(e){let t=S(e).activeViewConfig??{};return{filters:t.filters??null,groupBy:t.groupBy??null,order:Array.isArray(t.order)?[...t.order]:[],sort:Array.isArray(t.sort)?t.sort.map(e=>({...e})):[]}}function ie(e){return!!(e?.payload?.path&&e?.payload?.sourcePath&&e.payload.path===e.payload.sourcePath)}function O(e,n,r,i){let a=r.ui?.openPanel===n,s=!!S(i).editable;return`<button type="button" class="${t(o({variant:a?`primary`:`secondary`,pill:!0,extra:[`bases-toolbar-btn`,a?`is-active`:``]}))}" data-base-panel="${t(n)}"${s?``:` disabled`}>${t(e)}</button>`}function k(e,t=``){if(!e||e.type!==`group`||!t)return e;let n=(e.children??[]).flatMap(e=>{if(e?.type===`group`){let n=k(e,t);return n?[n]:[]}return e?.propertyId===t?[]:[e]});return{...e,children:n}}function A(e,t=``,n=e?.result){let r=S(n).activeViewConfig?.filters??null,i=R(r),a=t&&i?I(k(i,t),n):r;return JSON.stringify({filters:a,path:e?.payload?.path??``,source:e?.payload?.source??null,sourcePath:e?.payload?.sourcePath??``,view:n?.view?.id??e?.payload?.view??``})}function ae(e,t=``,n=e?.result){let r=e?.propertyValueOptions?.get(t)??null;return r&&r.cacheKey===A(e,t,n)?r.values??[]:[]}function j(e,t){return[O(`Sort`,`sort`,t,e),O(`Filter`,`filter`,t,e),O(`Properties`,`properties`,t,e)].join(``)}function M(e,{allowBlank:n=!1,selected:r=``}={}){let i=[];return n&&i.push(`<option value=""${r?``:` selected`}>Property</option>`),C(e).forEach(e=>{i.push(`<option value="${t(e.id)}"${e.id===r?` selected`:``}>${t(e.label)}</option>`)}),i.join(``)}function oe(e){let n=D(e),r=T(e,n.groupBy?.property)?.sortDirections??[{id:`asc`,label:`A → Z`},{id:`desc`,label:`Z → A`}],i=n.sort??[];return`
|
|
2
|
-
<section class="bases-panel-card">
|
|
3
|
-
<div class="bases-panel-section">
|
|
4
|
-
<div class="bases-panel-title">Group by</div>
|
|
5
|
-
<div class="bases-sort-row">
|
|
6
|
-
<select class="${t(a({extra:`bases-select bases-sort-property`}))}" data-base-group-by-property>
|
|
7
|
-
${M(e,{allowBlank:!0,selected:n.groupBy?.property??``})}
|
|
8
|
-
</select>
|
|
9
|
-
<select class="${t(a({extra:`bases-select bases-sort-direction`}))}" data-base-group-by-direction${n.groupBy?.property?``:` disabled`}>
|
|
10
|
-
${r.map(e=>`<option value="${t(e.id)}"${e.id===(n.groupBy?.direction??`asc`)?` selected`:``}>${t(e.label)}</option>`).join(``)}
|
|
11
|
-
</select>
|
|
12
|
-
<button type="button" class="${t(o({variant:`secondary`,size:`compact`}))}" data-base-clear-group-by${n.groupBy?.property?``:` disabled`}>Clear</button>
|
|
13
|
-
</div>
|
|
14
|
-
</div>
|
|
15
|
-
<div class="bases-panel-section">
|
|
16
|
-
<div class="bases-panel-title">Sort by</div>
|
|
17
|
-
<div class="bases-sort-list">
|
|
18
|
-
${i.map((n,r)=>{let s=T(e,n.property)?.sortDirections??[{id:`asc`,label:`A → Z`},{id:`desc`,label:`Z → A`}];return`
|
|
19
|
-
<div class="bases-sort-row">
|
|
20
|
-
<select class="${t(a({extra:`bases-select bases-sort-property`}))}" data-base-sort-property="${r}">
|
|
21
|
-
${M(e,{selected:n.property})}
|
|
22
|
-
</select>
|
|
23
|
-
<select class="${t(a({extra:`bases-select bases-sort-direction`}))}" data-base-sort-direction="${r}">
|
|
24
|
-
${s.map(e=>`<option value="${t(e.id)}"${e.id===n.direction?` selected`:``}>${t(e.label)}</option>`).join(``)}
|
|
25
|
-
</select>
|
|
26
|
-
<button type="button" class="${t(o({variant:`secondary`,size:`compact`}))}" data-base-sort-move="${r}:up"${r===0?` disabled`:``}>↑</button>
|
|
27
|
-
<button type="button" class="${t(o({variant:`secondary`,size:`compact`}))}" data-base-sort-move="${r}:down"${r===i.length-1?` disabled`:``}>↓</button>
|
|
28
|
-
<button type="button" class="${t(o({variant:`secondary`,size:`compact`}))}" data-base-sort-delete="${r}">Delete</button>
|
|
29
|
-
</div>
|
|
30
|
-
`}).join(``)}
|
|
31
|
-
</div>
|
|
32
|
-
<button type="button" class="${t(o({variant:`secondary`,size:`compact`}))}" data-base-sort-add>Add sort</button>
|
|
33
|
-
</div>
|
|
34
|
-
</section>
|
|
35
|
-
`}function N(e=[]){return e.join(`.`)}function P(e=``){return String(e??``).split(`.`).filter(e=>e!==``).map(e=>Number.parseInt(e,10)).filter(Number.isFinite)}function se(e=``){return JSON.stringify(String(e??``))}function F(e=``,t=`text`,n=`is`){let r=String(e??``).trim();return!r&&n!==`is`&&n!==`is not`?`""`:t===`boolean`?r===`false`?`false`:`true`:t===`number`&&Number.isFinite(Number(r))?String(Number(r)):se(r)}function ce(e,t=null){if(!e?.propertyId||!e?.operator)return``;let n=e.propertyId,r=t?.valueType??`text`;switch(e.operator){case`contains`:return`${n}.contains(${F(e.value,r,e.operator)})`;case`does not contain`:return`!${n}.contains(${F(e.value,r,e.operator)})`;case`starts with`:return`${n}.startsWith(${F(e.value,r,e.operator)})`;case`ends with`:return`${n}.endsWith(${F(e.value,r,e.operator)})`;case`is`:return`${n} == ${F(e.value,r,e.operator)}`;case`is not`:return`${n} != ${F(e.value,r,e.operator)}`;case`>`:case`>=`:case`<`:case`<=`:return`${n} ${e.operator} ${F(e.value,r,e.operator)}`;case`is empty`:return`${n}.isEmpty()`;case`is not empty`:return`!${n}.isEmpty()`;default:return``}}function I(e,t){if(!e||e.type!==`group`)return null;let n=(e.children??[]).map(e=>e?.type===`group`?I(e,t):ce(e,T(t,e?.propertyId))).filter(Boolean);return n.length===0?null:e.conjunction===`not`?{not:n}:{[e.conjunction]:n}}function L(e=``){let t=String(e??``).trim();return t?t===`true`||t===`false`?t:t===`null`?``:/^-?\d+(?:\.\d+)?$/u.test(t)?t:t.startsWith(`"`)&&t.endsWith(`"`)||t.startsWith(`'`)&&t.endsWith(`'`)?t.slice(1,-1).replace(/\\(["'])/gu,`$1`):t:``}function le(e=``){let t=String(e??``).trim(),n=[[/^!([A-Za-z0-9_.]+)\.isEmpty\(\)$/u,(e,t)=>({operator:`is not empty`,propertyId:t,type:`rule`,value:``})],[/^([A-Za-z0-9_.]+)\.isEmpty\(\)$/u,(e,t)=>({operator:`is empty`,propertyId:t,type:`rule`,value:``})],[/^!([A-Za-z0-9_.]+)\.contains\((.+)\)$/u,(e,t,n)=>({operator:`does not contain`,propertyId:t,type:`rule`,value:L(n)})],[/^([A-Za-z0-9_.]+)\.contains\((.+)\)$/u,(e,t,n)=>({operator:`contains`,propertyId:t,type:`rule`,value:L(n)})],[/^([A-Za-z0-9_.]+)\.startsWith\((.+)\)$/u,(e,t,n)=>({operator:`starts with`,propertyId:t,type:`rule`,value:L(n)})],[/^([A-Za-z0-9_.]+)\.endsWith\((.+)\)$/u,(e,t,n)=>({operator:`ends with`,propertyId:t,type:`rule`,value:L(n)})],[/^([A-Za-z0-9_.]+)\s*(==|!=|>=|<=|>|<)\s*(.+)$/u,(e,t,n,r)=>({operator:{"!=":`is not`,"==":`is`,"<":`<`,"<=":`<=`,">":`>`,">=":`>=`}[n]??n,propertyId:t,type:`rule`,value:L(r)})]];for(let[e,r]of n){let n=t.match(e);if(n)return r(...n)}return null}function R(e){if(!e)return p(`and`);if(typeof e==`string`){let t=le(e);return t?{children:[t],conjunction:`and`,type:`group`}:null}if(!f(e))return null;if(Array.isArray(e.and)){let t=e.and.map(e=>R(e)).flatMap(e=>e?.type===`group`&&e.conjunction===`and`&&e.children?.length===1&&e.children[0]?.type===`rule`?e.children:[e]);return t.every(Boolean)?{children:t,conjunction:`and`,type:`group`}:null}if(Array.isArray(e.or)){let t=e.or.map(e=>R(e)).flatMap(e=>e?.type===`group`&&e.conjunction===`and`&&e.children?.length===1&&e.children[0]?.type===`rule`?e.children:[e]);return t.every(Boolean)?{children:t,conjunction:`or`,type:`group`}:null}if(e.not!=null){let t=(Array.isArray(e.not)?e.not:(()=>{let t=R(e.not);return t?t.type===`group`&&t.conjunction===`or`?t.children??[]:[t]:[]})()).flatMap(e=>{let t=e?.type?e:R(e);return t?t.type===`group`&&t.conjunction===`and`&&t.children?.length===1&&t.children[0]?.type===`rule`?t.children:[t]:[null]});return t.every(Boolean)?{children:t,conjunction:`not`,type:`group`}:null}return null}function z(e){return e?typeof e==`string`?e:JSON.stringify(e,null,2):``}function ue(e=``){let t=String(e??``).trim();return t?t.startsWith(`{`)||t.startsWith(`[`)?JSON.parse(t):t:null}function B(e,t=[]){let n=e;for(let e of t)n=n?.children?.[e];return n??null}function V(e,t=[],n){if(t.length===0)return n(e);let[r,...i]=t;return{...e,children:(e.children??[]).map((e,t)=>t===r?V(e,i,n):e)}}function de(e,t=[]){if(t.length===0)return e;let n=t.slice(0,-1),r=t[t.length-1];return V(e,n,e=>({...e,children:(e.children??[]).filter((e,t)=>t!==r)}))}function H(e,t=[],n){return V(e,t,e=>({...e,children:[...e.children??[],n]}))}function U(e,t=``){return M(e,{allowBlank:!0,selected:t})}function fe(e={}){return String(e?.text??e?.value??``).trim()}function W(e,t){return e.ui.builderFilter??R(D(t).filters)??p(`and`)}function G(e,n,r,i){let o=N(r),s=E(e,n.propertyId),c=String(n.value??``).trim().toLowerCase(),l=ae(i,n.propertyId,e).map(e=>({count:e?.count,text:fe(e)})).filter((e,t,n)=>e.text&&n.findIndex(t=>t.text===e.text)===t),u=l.some(e=>e.text.toLowerCase()===c),d=l.filter(e=>!c||e.text.toLowerCase().includes(c)),f=!c||u?l:d.length>0?d:l,p=f.length>0&&![`is empty`,`is not empty`].includes(n.operator);return{encodedPath:o,operators:s,suggestionListId:`bases-filter-suggestions-${t(i.key)}-${t(o.replace(/\./g,`-`))}`,suggestionsEnabled:p,valueInputClasses:a({extra:p?`bases-filter-value bases-filter-value--suggestions`:`bases-filter-value`}),valueSuggestions:f,valueDisabled:[`is empty`,`is not empty`].includes(n.operator)}}function K(e,n=``){return e.suggestionsEnabled?`
|
|
36
|
-
<div class="bases-filter-suggestion-list" id="${e.suggestionListId}" role="listbox">
|
|
37
|
-
${e.valueSuggestions.slice(0,8).map(r=>`
|
|
38
|
-
<button
|
|
39
|
-
type="button"
|
|
40
|
-
class="bases-filter-suggestion"
|
|
41
|
-
data-base-filter-suggestion="${t(e.encodedPath)}"
|
|
42
|
-
data-base-filter-suggestion-value="${t(r.text)}"
|
|
43
|
-
role="option"
|
|
44
|
-
aria-selected="${r.text===String(n??``)?`true`:`false`}"
|
|
45
|
-
>
|
|
46
|
-
<span class="bases-filter-suggestion-label">${t(r.text)}</span>
|
|
47
|
-
${r.count==null?``:`<span class="bases-filter-suggestion-meta">${t(String(r.count))}</span>`}
|
|
48
|
-
</button>
|
|
49
|
-
`).join(``)}
|
|
50
|
-
</div>
|
|
51
|
-
`:``}function pe(e,n,r,i){let a=G(e,n,r,i);return`
|
|
52
|
-
<div class="bases-filter-value-combobox${a.suggestionsEnabled?` has-suggestions`:``}">
|
|
53
|
-
<input class="${t(a.valueInputClasses)}" type="text" value="${t(n.value??``)}" data-base-filter-value="${t(a.encodedPath)}"${a.suggestionsEnabled?` aria-controls="${a.suggestionListId}" aria-haspopup="listbox" aria-autocomplete="list" autocomplete="off"`:``}${a.valueDisabled?` disabled`:``}>
|
|
54
|
-
${K(a,n.value??``)}
|
|
55
|
-
</div>
|
|
56
|
-
`}function me(e,n,r,i){let s=G(e,n,r,i);return`
|
|
57
|
-
<div class="bases-filter-row">
|
|
58
|
-
<select class="${t(a({extra:`bases-select bases-filter-property`}))}" data-base-filter-property="${t(s.encodedPath)}">
|
|
59
|
-
${U(e,n.propertyId)}
|
|
60
|
-
</select>
|
|
61
|
-
<select class="${t(a({extra:`bases-select bases-filter-operator`}))}" data-base-filter-operator="${t(s.encodedPath)}">
|
|
62
|
-
${s.operators.map(e=>`<option value="${t(e)}"${e===n.operator?` selected`:``}>${t(e)}</option>`).join(``)}
|
|
63
|
-
</select>
|
|
64
|
-
${pe(e,n,r,i)}
|
|
65
|
-
<button type="button" class="${t(o({variant:`secondary`,size:`compact`}))}" data-base-filter-remove="${t(s.encodedPath)}">Delete</button>
|
|
66
|
-
</div>
|
|
67
|
-
`}function q(e,t,n,{fallbackToFullRender:r=!0}={}){let i=Z(e)?.querySelector?.(`[data-base-panel-slot]`)??null,a=N(n),o=i?.querySelector?.(`[data-base-filter-value="${a}"]`)??null,s=o?.parentElement?.classList?.contains(`bases-filter-value-combobox`)?o.parentElement:null,c=B(W(e,t),n);if(!o||!s||!c||c.type!==`rule`||typeof o.insertAdjacentHTML!=`function`)return r&&$(e,t),!1;let l=G(t,c,n,e);return s.classList.toggle(`has-suggestions`,l.suggestionsEnabled),o.className=l.valueInputClasses,o.disabled=l.valueDisabled,o.value!==String(c.value??``)&&(o.value=String(c.value??``)),l.suggestionsEnabled?(o.setAttribute(`aria-controls`,l.suggestionListId),o.setAttribute(`aria-haspopup`,`listbox`),o.setAttribute(`aria-autocomplete`,`list`),o.setAttribute(`autocomplete`,`off`)):(o.removeAttribute(`aria-controls`),o.removeAttribute(`aria-haspopup`),o.removeAttribute(`aria-autocomplete`),o.removeAttribute(`autocomplete`)),s.querySelector(`.bases-filter-suggestion-list`)?.remove?.(),l.suggestionsEnabled&&o.insertAdjacentHTML(`afterend`,K(l,c.value??``)),!0}function J(e,t,n=[]){if(e){if(e.type===`rule`){t(e,n);return}(e.children??[]).forEach((e,r)=>{J(e,t,[...n,r])})}}function Y(e,n,r,i,{isRoot:s=!1}={}){let c=N(r);return`
|
|
68
|
-
<div class="bases-filter-group"${s?` data-base-filter-root`:``}>
|
|
69
|
-
<div class="bases-filter-group-header">
|
|
70
|
-
<select class="${t(a({extra:`bases-select bases-filter-conjunction`}))}" data-base-filter-conjunction="${t(c)}">
|
|
71
|
-
${[`and`,`or`,`not`].map(e=>`<option value="${e}"${n.conjunction===e?` selected`:``}>${t({and:`All the following are true`,not:`None of the following are true`,or:`Any of the following are true`}[e])}</option>`).join(``)}
|
|
72
|
-
</select>
|
|
73
|
-
${s?``:`<button type="button" class="${t(o({variant:`secondary`,size:`compact`}))}" data-base-filter-remove="${t(c)}">Delete group</button>`}
|
|
74
|
-
</div>
|
|
75
|
-
<div class="bases-filter-children">
|
|
76
|
-
${(n.children??[]).map((t,n)=>t?.type===`group`?Y(e,t,[...r,n],i):me(e,t,[...r,n],i)).join(``)}
|
|
77
|
-
</div>
|
|
78
|
-
<div class="bases-filter-actions-row">
|
|
79
|
-
<button type="button" class="${t(o({variant:`secondary`,size:`compact`}))}" data-base-filter-add-rule="${t(c)}">Add filter</button>
|
|
80
|
-
<button type="button" class="${t(o({variant:`secondary`,size:`compact`}))}" data-base-filter-add-group="${t(c)}">Add filter group</button>
|
|
81
|
-
</div>
|
|
82
|
-
</div>
|
|
83
|
-
`}function he(e,n){let r=D(e).filters,i=n.ui.builderFilter??R(r);n.ui.builderFilter??(n.ui.builderFilter=i);let s=i?n.ui.filterMode??`builder`:`advanced`,c=n.ui.rawFilterText??z(r);return`
|
|
84
|
-
<section class="bases-panel-card">
|
|
85
|
-
<div class="bases-panel-title-row">
|
|
86
|
-
<div class="bases-panel-title">This view</div>
|
|
87
|
-
${i?`
|
|
88
|
-
<div class="bases-toggle-row">
|
|
89
|
-
<button type="button" class="${t(o({variant:s===`builder`?`primary`:`secondary`,size:`compact`}))}" data-base-filter-mode="builder">Builder</button>
|
|
90
|
-
<button type="button" class="${t(o({variant:s===`advanced`?`primary`:`secondary`,size:`compact`}))}" data-base-filter-mode="advanced">Advanced</button>
|
|
91
|
-
</div>
|
|
92
|
-
`:``}
|
|
93
|
-
</div>
|
|
94
|
-
${s===`advanced`?`
|
|
95
|
-
<label class="bases-filter-advanced-label">
|
|
96
|
-
<textarea class="${t(a({extra:`bases-filter-advanced`}))}" data-base-filter-advanced>${t(c)}</textarea>
|
|
97
|
-
</label>
|
|
98
|
-
<div class="bases-filter-actions-row">
|
|
99
|
-
<button type="button" class="${t(o({variant:`primary`,size:`compact`}))}" data-base-filter-save-advanced>Save filter</button>
|
|
100
|
-
</div>
|
|
101
|
-
`:Y(e,i??p(`and`),[],n,{isRoot:!0})}
|
|
102
|
-
</section>
|
|
103
|
-
`}function ge(e,n){let r=String(n.ui.propertySearch??``).trim().toLowerCase(),i=new Set(w(e)),o=C(e).filter(e=>!r||e.label.toLowerCase().includes(r)||e.id.toLowerCase().includes(r));return`
|
|
104
|
-
<section class="bases-panel-card">
|
|
105
|
-
<label class="bases-properties-search">
|
|
106
|
-
<input class="${t(a({extra:`bases-properties-search-input`}))}" type="search" value="${t(n.ui.propertySearch??``)}" placeholder="Find property" data-base-properties-search>
|
|
107
|
-
</label>
|
|
108
|
-
<div class="bases-properties-list" data-base-properties-list>
|
|
109
|
-
${o.map(e=>`
|
|
110
|
-
<label class="bases-property-option">
|
|
111
|
-
<input type="checkbox" data-base-property-toggle="${t(e.id)}"${i.has(e.id)?` checked`:``}>
|
|
112
|
-
<span class="bases-property-option-label">${t(e.label)}</span>
|
|
113
|
-
<span class="bases-property-option-meta">${t(e.kind)}</span>
|
|
114
|
-
</label>
|
|
115
|
-
`).join(``)}
|
|
116
|
-
</div>
|
|
117
|
-
</section>
|
|
118
|
-
`}function _e(e){let t=e?.querySelector?.(`[data-base-properties-list]`)??null,n=e?.querySelector?.(`[data-base-properties-search]`)??null,r=typeof document<`u`?document.activeElement:null,i=null;if(n&&r===n){let e=typeof n.selectionStart==`number`?n.selectionStart:null;i={selectionEnd:typeof n.selectionEnd==`number`?n.selectionEnd:e,selectionStart:e,type:`properties-search`}}else if(r?.dataset?.baseFilterValue!=null){let t=String(r.dataset.baseFilterValue),n=e?.querySelector?.(`[data-base-filter-value="${t}"]`)??null;if(n&&r===n){let e=typeof n.selectionStart==`number`?n.selectionStart:null;i={path:t,selectionEnd:typeof n.selectionEnd==`number`?n.selectionEnd:e,selectionStart:e,type:`filter-value`}}}return{focusedControl:i,propertiesListScrollTop:t?t.scrollTop:null}}function ve(e,t){if(t){if(t.propertiesListScrollTop!=null){let n=e?.querySelector?.(`[data-base-properties-list]`)??null;n&&(n.scrollTop=t.propertiesListScrollTop)}if(t.focusedControl?.type===`properties-search`){let n=e?.querySelector?.(`[data-base-properties-search]`)??null;n&&(n.focus?.(),typeof n.setSelectionRange==`function`&&t.focusedControl.selectionStart!=null&&n.setSelectionRange(t.focusedControl.selectionStart,t.focusedControl.selectionEnd??t.focusedControl.selectionStart));return}if(t.focusedControl?.type===`filter-value`&&t.focusedControl.path!=null){let n=e?.querySelector?.(`[data-base-filter-value="${t.focusedControl.path}"]`)??null;n&&(n.focus?.(),typeof n.setSelectionRange==`function`&&t.focusedControl.selectionStart!=null&&n.setSelectionRange(t.focusedControl.selectionStart,t.focusedControl.selectionEnd??t.focusedControl.selectionStart))}}}function X(e,t){if(!t.ui?.openPanel)return``;if(!S(e).editable)return`<section class="bases-panel-card"><div class="bases-readonly-note">Inline base previews are read-only. Open the .base file to edit its sort, filter, and properties.</div></section>`;switch(t.ui.openPanel){case`filter`:return he(e,t);case`properties`:return ge(e,t);default:return oe(e)}}function ye(e,n){return`
|
|
119
|
-
<section class="bases-shell" data-base-shell-key="${t(n.key)}">
|
|
120
|
-
<header class="bases-toolbar">
|
|
121
|
-
<div class="bases-toolbar-main">
|
|
122
|
-
<div class="${t(s({pill:!0,extra:`bases-tabs`}))}" data-base-tabs>
|
|
123
|
-
${x(e)}
|
|
124
|
-
</div>
|
|
125
|
-
<div class="bases-meta" data-base-meta>${t(String(e.totalRows??0))} results</div>
|
|
126
|
-
</div>
|
|
127
|
-
<div class="bases-toolbar-actions">
|
|
128
|
-
<div class="bases-toolbar-edit-actions" data-base-action-slot>${j(e,n)}</div>
|
|
129
|
-
<label class="bases-search-shell" aria-label="Search this base">
|
|
130
|
-
<svg class="bases-search-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
131
|
-
<circle cx="11" cy="11" r="7"></circle>
|
|
132
|
-
<path d="m20 20-3.5-3.5"></path>
|
|
133
|
-
</svg>
|
|
134
|
-
<input class="${t(a({extra:`bases-search-input`}))}" type="search" value="${t(n.search)}" placeholder="Search this base" aria-label="Search this base">
|
|
135
|
-
</label>
|
|
136
|
-
<button type="button" class="${t(o({variant:`secondary`,pill:!0,extra:`bases-export-btn`}))}">Export CSV</button>
|
|
137
|
-
</div>
|
|
138
|
-
</header>
|
|
139
|
-
<div class="bases-panels" data-base-panel-slot>${X(e,n)}</div>
|
|
140
|
-
<div data-base-summary-slot>${y(e.summaries)}</div>
|
|
141
|
-
<div class="bases-content" data-base-content>${b(e)}</div>
|
|
142
|
-
</section>
|
|
143
|
-
`}function Z(e){return e?.placeholder?.querySelector?e.placeholder.querySelector(`[data-base-shell-key="${e.key}"]`)??e.placeholder.querySelector(`.bases-shell`):null}function be(e){e?.classList&&(e.classList.add(`is-hydrated`),e.classList.remove(`diagram-preview-shell`))}function Q(e,t,{actions:n=!0,body:r=!0,meta:i=!0,panel:a=!0,summary:o=!0,tabs:s=!0}={}){let c=Z(e);if(!c?.querySelector){e.placeholder.innerHTML=ye(t,e),be(e.placeholder);return}let l=c.querySelector(`[data-base-tabs]`);s&&l&&(l.innerHTML=x(t));let u=c.querySelector(`[data-base-meta]`);i&&u&&(u.textContent=`${String(t.totalRows??0)} results`);let d=c.querySelector(`[data-base-action-slot]`);n&&d&&(d.innerHTML=j(t,e));let f=c.querySelector(`[data-base-panel-slot]`);if(a&&f){let n=_e(f);f.innerHTML=X(t,e),ve(f,n)}let p=c.querySelector(`[data-base-summary-slot]`);o&&p&&(p.innerHTML=y(t.summaries));let m=c.querySelector(`[data-base-content]`);r&&m&&(m.innerHTML=b(t));let h=c.querySelector(`.bases-search-input`);h&&h.value!==e.search&&(h.value=e.search)}function $(e,t){Q(e,t,{actions:!1,body:!1,meta:!1,summary:!1,tabs:!1})}var xe=class{constructor({getActiveFilePath:e=()=>``,getSession:t=()=>null,onOpenFile:n,previewElement:r,replaceBaseSource:i=null,toastController:a,vaultApiClient:o}){this.getActiveFilePath=e,this.getSession=t,this.onOpenFile=n,this.previewElement=r,this.replaceBaseSource=i,this.toastController=a,this.vaultApiClient=o,this.entries=new Map,this.searchTimers=new Map,this.applyFilterSuggestion=(e,t,n)=>{this.updateBuilderFilter(e,e=>V(e,t,e=>({...e,value:n})))},this.persistBuilderFilter=e=>{let t=W(e,e.result);e.ui.builderFilter=t,this.updateViewConfig(e,n=>(n.filters=I(t,e.result),n))},this.handlePointerDown=e=>{let t=e.target.closest(`[data-base-filter-suggestion]`);if(!t)return;let n=e.target.closest(`[data-base-shell-key]`),r=n?this.entries.get(n.dataset.baseShellKey||``):null;if(!r)return;e.preventDefault();let i=P(t.dataset.baseFilterSuggestion||``),a=t.dataset.baseFilterSuggestionValue||``;this.applyFilterSuggestion(r,i,a)},this.handleClick=e=>{let t=e.target.closest(`[data-base-open-file]`);if(t){e.preventDefault(),this.onOpenFile?.(t.dataset.baseOpenFile||``);return}let n=e.target.closest(`[data-base-shell-key]`),r=n?this.entries.get(n.dataset.baseShellKey||``):null;if(!r)return;let i=e.target.closest(`.bases-view-tab`);if(i){r.payload.view=i.dataset.baseView||``,r.ui.openPanel=``,this.renderEntry(r);return}let a=e.target.closest(`[data-base-panel]`);if(a){let e=a.dataset.basePanel||``;r.ui.openPanel=r.ui.openPanel===e?``:e,r.ui.rawFilterText=z(D(r.result).filters),$(r,r.result);return}if(e.target.closest(`.bases-export-btn`)){this.exportEntry(r);return}if(e.target.closest(`[data-base-sort-add]`)){this.updateViewConfig(r,e=>{let t=new Set((e.sort??[]).map(e=>e.property)),n=C(r.result).find(e=>!t.has(e.id))?.id??`file.name`;return e.sort=[...e.sort??[],{direction:`asc`,property:n}],e});return}let o=e.target.closest(`[data-base-sort-delete]`);if(o){let e=Number.parseInt(o.dataset.baseSortDelete||``,10);this.updateViewConfig(r,t=>(t.sort=(t.sort??[]).filter((t,n)=>n!==e),t));return}let s=e.target.closest(`[data-base-sort-move]`);if(s){let[e,t]=String(s.dataset.baseSortMove||``).split(`:`),n=Number.parseInt(e,10);this.updateViewConfig(r,e=>{let r=[...e.sort??[]],i=t===`up`?n-1:n+1;return i<0||i>=r.length?e:([r[n],r[i]]=[r[i],r[n]],e.sort=r,e)});return}if(e.target.closest(`[data-base-clear-group-by]`)){this.updateViewConfig(r,e=>(e.groupBy=null,e));return}let c=e.target.closest(`[data-base-filter-mode]`);if(c){r.ui.filterMode=c.dataset.baseFilterMode||`builder`,r.ui.filterMode===`advanced`&&(r.ui.rawFilterText=z(D(r.result).filters),r.ui.builderFilter=null),$(r,r.result);return}if(e.target.closest(`[data-base-filter-save-advanced]`)){this.saveAdvancedFilter(r);return}let l=e.target.closest(`[data-base-filter-add-rule]`);if(l){let e=P(l.dataset.baseFilterAddRule||``);this.updateBuilderFilter(r,t=>H(t,e,{operator:`is`,propertyId:C(r.result)[0]?.id??`file.name`,type:`rule`,value:``}));return}let u=e.target.closest(`[data-base-filter-add-group]`);if(u){let e=P(u.dataset.baseFilterAddGroup||``);this.updateBuilderFilter(r,t=>H(t,e,p(`and`)));return}let d=e.target.closest(`[data-base-filter-remove]`);if(d){let e=P(d.dataset.baseFilterRemove||``);this.updateBuilderFilter(r,t=>de(t,e));return}let f=e.target.closest(`[data-base-filter-suggestion]`);if(f){if(e.preventDefault?.(),e.detail!=null&&e.detail!==0)return;let t=P(f.dataset.baseFilterSuggestion||``),n=f.dataset.baseFilterSuggestionValue||``;this.applyFilterSuggestion(r,t,n)}},this.handleInput=e=>{let t=e.target.closest(`.bases-search-input`);if(t){let e=t.closest(`[data-base-shell-key]`),n=e?this.entries.get(e.dataset.baseShellKey||``):null;if(!n)return;n.search=t.value||``,clearTimeout(this.searchTimers.get(n.key)),this.searchTimers.set(n.key,setTimeout(()=>{n.payload.search=n.search,this.renderEntry(n)},180));return}let n=e.target.closest(`[data-base-properties-search]`);if(n){let e=n.closest(`[data-base-shell-key]`),t=e?this.entries.get(e.dataset.baseShellKey||``):null;if(!t)return;t.ui.propertySearch=n.value||``,$(t,t.result);return}let r=e.target.closest(`[data-base-filter-advanced]`);if(r){let e=r.closest(`[data-base-shell-key]`),t=e?this.entries.get(e.dataset.baseShellKey||``):null;if(!t)return;t.ui.rawFilterText=r.value||``;return}let i=e.target.closest(`[data-base-filter-value]`);if(i){let e=i.closest(`[data-base-shell-key]`),t=e?this.entries.get(e.dataset.baseShellKey||``):null;if(!t)return;let n=P(i.dataset.baseFilterValue||``),r=t.ui.builderFilter??R(D(t.result).filters)??p(`and`);t.ui.builderFilter=V(r,n,e=>({...e,value:i.value||``})),q(t,t.result,n)}},this.handleChange=e=>{let t=e.target.closest(`[data-base-shell-key]`),n=t?this.entries.get(t.dataset.baseShellKey||``):null;if(!n)return;let r=e.target.closest(`[data-base-group-by-property]`);if(r){this.updateViewConfig(n,e=>(e.groupBy=r.value?{direction:e.groupBy?.direction??`asc`,property:r.value}:null,e));return}let i=e.target.closest(`[data-base-group-by-direction]`);if(i){this.updateViewConfig(n,e=>(e.groupBy=e.groupBy?.property?{direction:i.value||`asc`,property:e.groupBy.property}:null,e));return}let a=e.target.closest(`[data-base-sort-property]`);if(a){let e=Number.parseInt(a.dataset.baseSortProperty||``,10);this.updateViewConfig(n,t=>(t.sort=(t.sort??[]).map((t,n)=>n===e?{...t,property:a.value}:t),t));return}let o=e.target.closest(`[data-base-sort-direction]`);if(o){let e=Number.parseInt(o.dataset.baseSortDirection||``,10);this.updateViewConfig(n,t=>(t.sort=(t.sort??[]).map((t,n)=>n===e?{...t,direction:o.value||`asc`}:t),t));return}let s=e.target.closest(`[data-base-property-toggle]`);if(s){let e=s.dataset.basePropertyToggle||``;this.updateViewConfig(n,t=>{let r=t.order?.length>0?[...t.order]:w(n.result),i=r.indexOf(e);return s.checked&&i===-1&&r.push(e),!s.checked&&i>=0&&r.splice(i,1),t.order=r,t});return}let c=e.target.closest(`[data-base-filter-conjunction]`);if(c){let e=P(c.dataset.baseFilterConjunction||``);this.updateBuilderFilter(n,t=>V(t,e,e=>({...e,conjunction:c.value||`and`})));return}let l=e.target.closest(`[data-base-filter-property]`);if(l){let e=P(l.dataset.baseFilterProperty||``);(async()=>{await this.updateBuilderFilter(n,t=>V(t,e,e=>{let t=E(n.result,l.value)[0]??`is`;return{...e,operator:t,propertyId:l.value,value:``}})),await this.ensurePropertyValues(n,l.value)})();return}let u=e.target.closest(`[data-base-filter-operator]`);if(u){let e=P(u.dataset.baseFilterOperator||``);this.updateBuilderFilter(n,t=>V(t,e,e=>({...e,operator:u.value||`is`})));return}e.target.closest(`[data-base-filter-value]`)&&this.persistBuilderFilter(n)},this.handleFocusIn=e=>{let t=e.target.closest(`[data-base-filter-value]`);if(!t)return;let n=t.closest(`[data-base-shell-key]`),r=n?this.entries.get(n.dataset.baseShellKey||``):null;if(!r)return;let i=P(t.dataset.baseFilterValue||``),a=R(D(r.result).filters),o=a?B(a,i):null;o?.propertyId&&this.ensurePropertyValues(r,o.propertyId)},this.previewElement?.addEventListener(`pointerdown`,this.handlePointerDown),this.previewElement?.addEventListener(`click`,this.handleClick),this.previewElement?.addEventListener(`input`,this.handleInput),this.previewElement?.addEventListener(`change`,this.handleChange),this.previewElement?.addEventListener(`focusin`,this.handleFocusIn)}ensureEntryState(e){e.ui||={builderFilter:null,filterMode:`builder`,openPanel:``,propertySearch:``,rawFilterText:``},Object.prototype.hasOwnProperty.call(e.ui,`builderFilter`)||(e.ui.builderFilter=null),e.propertyValueOptions||=new Map}destroy(){this.previewElement?.removeEventListener(`pointerdown`,this.handlePointerDown),this.previewElement?.removeEventListener(`click`,this.handleClick),this.previewElement?.removeEventListener(`input`,this.handleInput),this.previewElement?.removeEventListener(`change`,this.handleChange),this.previewElement?.removeEventListener(`focusin`,this.handleFocusIn),this.searchTimers.forEach(e=>clearTimeout(e)),this.searchTimers.clear(),this.entries.clear()}reconcileEmbeds(e=this.previewElement){e&&Array.from(e.querySelectorAll(`.bases-embed-placeholder[data-base-key]`)).forEach(e=>{let t=e.dataset.baseKey||l(),n=this.entries.get(t),r={path:e.dataset.basePath||``,search:``,source:e.dataset.baseSource||null,sourcePath:e.dataset.baseSourcePath||``,view:e.dataset.baseView||``},i=n??{key:t,payload:r,placeholder:e,propertyValueOptions:new Map,requestVersion:0,result:null,search:``,ui:{builderFilter:null,filterMode:`builder`,openPanel:``,propertySearch:``,rawFilterText:``}};i.payload=r,i.placeholder=e,this.entries.set(t,i),this.renderEntry(i)})}async renderStandalone({filePath:e,renderHost:t,source:n=null}){let r=`standalone:${e}`,i=this.entries.get(r)??{key:r,payload:{path:e,search:``,source:n,sourcePath:e,view:``},placeholder:t,propertyValueOptions:new Map,requestVersion:0,result:null,search:``,ui:{builderFilter:null,filterMode:`builder`,openPanel:``,propertySearch:``,rawFilterText:``}};i.placeholder=t,i.payload.path=e,i.payload.source=typeof n==`string`?n:null,i.payload.sourcePath=e,this.entries.set(r,i),await this.renderEntry(i)}async renderEntry(e){if(this.ensureEntryState(e),!e?.placeholder?.isConnected)return;let n=(e.requestVersion??0)+1;e.requestVersion=n;let r=!!Z(e);r||(e.placeholder.innerHTML=`<div class="preview-shell">Loading base…</div>`);try{let t=await this.vaultApiClient.queryBase({activeFilePath:this.getActiveFilePath?.()??``,...e.payload});if(n!==e.requestVersion||!e?.placeholder?.isConnected)return;e.result=t.result,e.ui.builderFilter=R(D(e.result).filters),e.ui.rawFilterText||(e.ui.rawFilterText=z(D(e.result).filters)),Q(e,e.result)}catch(i){if(n!==e.requestVersion||!e?.placeholder?.isConnected)return;if(r){let n=Z(e)?.querySelector?.(`[data-base-content]`)??null;if(n){n.innerHTML=`<div class="preview-shell">Failed to load base: ${t(i.message||`Unknown error`)}</div>`;return}}e.placeholder.innerHTML=`<div class="preview-shell">Failed to load base: ${t(i.message||`Unknown error`)}</div>`}}async exportEntry(e){this.ensureEntryState(e);try{let t=await this.vaultApiClient.exportBaseCsv({activeFilePath:this.getActiveFilePath?.()??``,...e.payload});i(t.blob,r(t.contentDisposition,`base.csv`),{removeDelayMs:0,revokeDelayMs:0})}catch(e){this.toastController?.show?.(e.message||`Failed to export base CSV`)}}async ensurePropertyValues(e,t=``){if(this.ensureEntryState(e),!t)return;let n=A(e,t);if((e.propertyValueOptions.get(t)??null)?.cacheKey!==n)try{let r=await this.vaultApiClient.queryBasePropertyValues({activeFilePath:this.getActiveFilePath?.()??``,...e.payload,propertyId:t});if(e.propertyValueOptions.set(t,{cacheKey:n,values:r.result?.values??[]}),e.result&&e.ui.openPanel===`filter`){let n=!1;J(W(e,e.result),(r,i)=>{r.propertyId===t&&(n=q(e,e.result,i,{fallbackToFullRender:!1})||n)}),n||$(e,e.result)}}catch{e.propertyValueOptions.set(t,{cacheKey:n,values:[]})}}async applyTransformedSource(e,t){if(this.ensureEntryState(e),ie(e)){e.payload.source=t.source,this.replaceBaseSource?.({path:e.payload.path,source:t.source});return}await this.vaultApiClient.writeFile({content:t.source,path:e.payload.path}),e.payload.source=null}async updateViewConfig(e,t){if(this.ensureEntryState(e),!e?.result||!S(e.result).editable)return;let n=t(D(e.result));try{let t=(await this.vaultApiClient.transformBase({activeFilePath:this.getActiveFilePath?.()??``,mutation:{config:n,type:`set-view-config`,view:e.result.view.id},...e.payload})).result;await this.applyTransformedSource(e,t),e.result=t.result,e.ui.rawFilterText=z(D(e.result).filters),Q(e,e.result)}catch(e){this.toastController?.show?.(e.message||`Failed to update base`)}}async updateBuilderFilter(e,t){this.ensureEntryState(e);let n=t(e.ui.builderFilter??R(D(e.result).filters)??p(`and`));e.ui.builderFilter=n,await this.updateViewConfig(e,t=>(t.filters=I(n,e.result),t))}async saveAdvancedFilter(e){this.ensureEntryState(e);try{let t=ue(e.ui.rawFilterText??``);e.ui.builderFilter=R(t),await this.updateViewConfig(e,e=>(e.filters=t,e))}catch(e){this.toastController?.show?.(e.message||`Invalid advanced filter`)}}};export{xe as BasesPreviewController};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
function e(){return typeof window>`u`?globalThis:window}function t(t,n){let r=e();return typeof r.requestIdleCallback==`function`?r.requestIdleCallback(t,{timeout:n}):r.setTimeout(()=>t({didTimeout:!1,timeRemaining:()=>0}),1)}function n(t){if(t===null)return;let n=e();if(typeof n.cancelIdleCallback==`function`){n.cancelIdleCallback(t);return}n.clearTimeout(t)}function r(e,t,n){if(!e||!t)return!1;let r=t.getBoundingClientRect(),i=e.getBoundingClientRect();return i.bottom>=r.top-n&&i.top<=r.bottom+n}function i(t,n,{removeDelayMs:r=3e4,revokeDelayMs:i=r}={}){let a=e(),o=URL.createObjectURL(t),s=document.createElement(`a`);s.href=o,s.download=n,s.style&&(s.style.display=`none`),document.body.appendChild(s),s.click(),r>0?a.setTimeout(()=>s.remove(),r):s.remove(),a.setTimeout(()=>URL.revokeObjectURL(o),i)}function a(e=``,t=`download`){let n=String(e).match(/filename\*=UTF-8''([^;]+)/iu);if(n)try{return decodeURIComponent(n[1])}catch{return t}return String(e).match(/filename="([^"]+)"/iu)?.[1]||t}export{t as a,a as i,i as n,r,n as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
function e(...e){return e.flat().flatMap(e=>e&&typeof e==`object`?Object.keys(e).filter(t=>e[t]):e||[]).join(` `)}function t(t={}){return e(`ui-input`,t.extra??[])}function n(t={}){let{variant:n=`secondary`,size:r=`md`,toggle:i=!1,toolbar:a=!1,action:o=!1,wide:s=!1,surface:c=!1,pill:l=!1,hidden:u=!1,active:d=!1,extra:f=[]}=t;return e(`ui-button`,n&&`ui-button--${n}`,r!==`md`&&`ui-button--${r}`,{"ui-button--toggle":i,"ui-button--toolbar":a,"ui-button--action":o,"ui-button--wide":s,"ui-button--surface":c,"ui-button--pill":l,active:d,hidden:u},f)}export{e as n,t as r,n as t};
|