cursedbelt 1.0.0 → 2.3.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.
- package/dist/client/index.js +1 -1
- package/dist/core/category/index.d.ts.map +1 -1
- package/dist/core/category/index.js +2 -1
- package/dist/core/category/index.js.map +1 -1
- package/dist/core/category/types.js +1 -1
- package/dist/core/category/types.js.map +1 -1
- package/dist/core/file-tree/fileTreeModel.d.ts +49 -0
- package/dist/core/file-tree/fileTreeModel.d.ts.map +1 -1
- package/dist/core/file-tree/fileTreeModel.js +84 -0
- package/dist/core/file-tree/fileTreeModel.js.map +1 -1
- package/dist/core/layout/index.js +1 -1
- package/dist/core/layout/index.js.map +1 -1
- package/dist/core/media/index.js +1 -1
- package/dist/core/media/index.js.map +1 -1
- package/dist/core/media/types.js +1 -1
- package/dist/core/media/types.js.map +1 -1
- package/dist/core/media/uploadLimits.js +1 -1
- package/dist/core/media/uploadLimits.js.map +1 -1
- package/dist/core/sharing/model.d.ts +1 -1
- package/dist/ctgr/index.js +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/react/activity-bar/ActivityBar.d.ts +17 -0
- package/dist/react/activity-bar/ActivityBar.d.ts.map +1 -1
- package/dist/react/activity-bar/ActivityBar.js.map +1 -1
- package/dist/react/analytics/index.d.ts +1 -1
- package/dist/react/analytics/index.js +1 -1
- package/dist/react/chat/MessageComposer.d.ts.map +1 -1
- package/dist/react/chat/MessageComposer.js +5 -4
- package/dist/react/chat/MessageComposer.js.map +1 -1
- package/dist/react/components/Button.d.ts.map +1 -1
- package/dist/react/components/Button.js +3 -2
- package/dist/react/components/Button.js.map +1 -1
- package/dist/react/components/Checkbox.d.ts +19 -3
- package/dist/react/components/Checkbox.d.ts.map +1 -1
- package/dist/react/components/Checkbox.js +29 -12
- package/dist/react/components/Checkbox.js.map +1 -1
- package/dist/react/components/CodeArea.d.ts.map +1 -1
- package/dist/react/components/CodeArea.js +2 -1
- package/dist/react/components/CodeArea.js.map +1 -1
- package/dist/react/components/Collapsible.d.ts.map +1 -1
- package/dist/react/components/Collapsible.js +2 -1
- package/dist/react/components/Collapsible.js.map +1 -1
- package/dist/react/components/ComboboxField.d.ts.map +1 -1
- package/dist/react/components/ComboboxField.js +3 -2
- package/dist/react/components/ComboboxField.js.map +1 -1
- package/dist/react/components/CopyButton.d.ts.map +1 -1
- package/dist/react/components/CopyButton.js +2 -1
- package/dist/react/components/CopyButton.js.map +1 -1
- package/dist/react/components/DataTable/ColumnChecklist.d.ts.map +1 -1
- package/dist/react/components/DataTable/ColumnChecklist.js +2 -1
- package/dist/react/components/DataTable/ColumnChecklist.js.map +1 -1
- package/dist/react/components/DataTable/Pagination.d.ts.map +1 -1
- package/dist/react/components/DataTable/Pagination.js +2 -1
- package/dist/react/components/DataTable/Pagination.js.map +1 -1
- package/dist/react/components/DataTable/SortHeader.d.ts.map +1 -1
- package/dist/react/components/DataTable/SortHeader.js +2 -1
- package/dist/react/components/DataTable/SortHeader.js.map +1 -1
- package/dist/react/components/DataTable/TableFilterBuilder.d.ts +61 -0
- package/dist/react/components/DataTable/TableFilterBuilder.d.ts.map +1 -0
- package/dist/react/components/DataTable/{FilterBuilder.js → TableFilterBuilder.js} +26 -3
- package/dist/react/components/DataTable/TableFilterBuilder.js.map +1 -0
- package/dist/react/components/DataTable/Toolbar.d.ts +1 -1
- package/dist/react/components/DataTable/Toolbar.js +3 -3
- package/dist/react/components/DataTable/Toolbar.js.map +1 -1
- package/dist/react/components/DataTable/cells/LinkCell.d.ts.map +1 -1
- package/dist/react/components/DataTable/cells/LinkCell.js +2 -1
- package/dist/react/components/DataTable/cells/LinkCell.js.map +1 -1
- package/dist/react/components/DataTable/index.d.ts +1 -1
- package/dist/react/components/DataTable/index.d.ts.map +1 -1
- package/dist/react/components/DataTable/index.js +4 -1
- package/dist/react/components/DataTable/index.js.map +1 -1
- package/dist/react/components/DragHandle.d.ts.map +1 -1
- package/dist/react/components/DragHandle.js +2 -1
- package/dist/react/components/DragHandle.js.map +1 -1
- package/dist/react/components/EmojiField.d.ts.map +1 -1
- package/dist/react/components/EmojiField.js +2 -1
- package/dist/react/components/EmojiField.js.map +1 -1
- package/dist/react/components/EventTimeline.d.ts +3 -2
- package/dist/react/components/EventTimeline.d.ts.map +1 -1
- package/dist/react/components/EventTimeline.js +3 -2
- package/dist/react/components/EventTimeline.js.map +1 -1
- package/dist/react/components/IconButton.d.ts +1 -1
- package/dist/react/components/IconButton.js +1 -1
- package/dist/react/components/InfoHint.d.ts.map +1 -1
- package/dist/react/components/InfoHint.js +5 -4
- package/dist/react/components/InfoHint.js.map +1 -1
- package/dist/react/components/InheritBadge.js +1 -1
- package/dist/react/components/InheritBadge.js.map +1 -1
- package/dist/react/components/InlineEditableText.d.ts.map +1 -1
- package/dist/react/components/InlineEditableText.js +2 -1
- package/dist/react/components/InlineEditableText.js.map +1 -1
- package/dist/react/components/MeterList.d.ts.map +1 -1
- package/dist/react/components/MeterList.js +2 -1
- package/dist/react/components/MeterList.js.map +1 -1
- package/dist/react/components/PathText.d.ts +2 -2
- package/dist/react/components/PathText.d.ts.map +1 -1
- package/dist/react/components/PathText.js +2 -1
- package/dist/react/components/PathText.js.map +1 -1
- package/dist/react/components/RatingField.d.ts.map +1 -1
- package/dist/react/components/RatingField.js +2 -1
- package/dist/react/components/RatingField.js.map +1 -1
- package/dist/react/components/SecretInput.js +3 -2
- package/dist/react/components/SecretInput.js.map +1 -1
- package/dist/react/components/SegmentedControl.d.ts.map +1 -1
- package/dist/react/components/SegmentedControl.js +2 -1
- package/dist/react/components/SegmentedControl.js.map +1 -1
- package/dist/react/components/StarRating.d.ts.map +1 -1
- package/dist/react/components/StarRating.js +9 -5
- package/dist/react/components/StarRating.js.map +1 -1
- package/dist/react/components/StatStrip.d.ts.map +1 -1
- package/dist/react/components/StatStrip.js +2 -1
- package/dist/react/components/StatStrip.js.map +1 -1
- package/dist/react/components/StatTile.d.ts.map +1 -1
- package/dist/react/components/StatTile.js +3 -2
- package/dist/react/components/StatTile.js.map +1 -1
- package/dist/react/components/Tabs.d.ts.map +1 -1
- package/dist/react/components/Tabs.js +2 -1
- package/dist/react/components/Tabs.js.map +1 -1
- package/dist/react/components/TruncatedText.d.ts +2 -1
- package/dist/react/components/TruncatedText.d.ts.map +1 -1
- package/dist/react/components/TruncatedText.js +2 -1
- package/dist/react/components/TruncatedText.js.map +1 -1
- package/dist/react/components/calendar/MonthGrid.d.ts.map +1 -1
- package/dist/react/components/calendar/MonthGrid.js +2 -1
- package/dist/react/components/calendar/MonthGrid.js.map +1 -1
- package/dist/react/components/calendar/WeekView.d.ts.map +1 -1
- package/dist/react/components/calendar/WeekView.js +2 -1
- package/dist/react/components/calendar/WeekView.js.map +1 -1
- package/dist/react/components/revealOnHover.d.ts.map +1 -1
- package/dist/react/components/revealOnHover.js +2 -1
- package/dist/react/components/revealOnHover.js.map +1 -1
- package/dist/react/file-tree/FileTree.d.ts +50 -1
- package/dist/react/file-tree/FileTree.d.ts.map +1 -1
- package/dist/react/file-tree/FileTree.js +234 -6
- package/dist/react/file-tree/FileTree.js.map +1 -1
- package/dist/react/file-tree/fileTree.css +52 -0
- package/dist/react/filter-rail/FilterRail.d.ts.map +1 -1
- package/dist/react/filter-rail/FilterRail.js +5 -4
- package/dist/react/filter-rail/FilterRail.js.map +1 -1
- package/dist/react/folder-tree/FolderTreeRail.d.ts.map +1 -1
- package/dist/react/folder-tree/FolderTreeRail.js +2 -1
- package/dist/react/folder-tree/FolderTreeRail.js.map +1 -1
- package/dist/react/index.d.ts +5 -1
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +5 -1
- package/dist/react/index.js.map +1 -1
- package/dist/react/layoutEngine/index.js +1 -1
- package/dist/react/layoutEngine/index.js.map +1 -1
- package/dist/react/lib/field.d.ts.map +1 -1
- package/dist/react/lib/field.js +3 -2
- package/dist/react/lib/field.js.map +1 -1
- package/dist/react/lib/floatingStyles.d.ts.map +1 -1
- package/dist/react/lib/floatingStyles.js +2 -1
- package/dist/react/lib/floatingStyles.js.map +1 -1
- package/dist/react/lib/tapTarget.d.ts +96 -0
- package/dist/react/lib/tapTarget.d.ts.map +1 -0
- package/dist/react/lib/tapTarget.js +96 -0
- package/dist/react/lib/tapTarget.js.map +1 -0
- package/dist/react/media/VideoTrimmer.d.ts +1 -1
- package/dist/react/media/VideoTrimmer.js +1 -1
- package/dist/react/media/denseGallery.css +3 -3
- package/dist/react/media/ffmpegWasm.js +2 -2
- package/dist/react/media/ffmpegWasm.js.map +1 -1
- package/dist/react/media/videoPlayer.css +42 -0
- package/dist/react/namespace/NamespaceTargetCapsule.d.ts +2 -2
- package/dist/react/namespace/NamespaceTargetCapsule.d.ts.map +1 -1
- package/dist/react/nav/BreadcrumbTrail.d.ts.map +1 -1
- package/dist/react/nav/BreadcrumbTrail.js +4 -3
- package/dist/react/nav/BreadcrumbTrail.js.map +1 -1
- package/dist/react/nav/HubTileGrid.d.ts.map +1 -1
- package/dist/react/nav/HubTileGrid.js +2 -1
- package/dist/react/nav/HubTileGrid.js.map +1 -1
- package/dist/react/nav/SideNav.d.ts.map +1 -1
- package/dist/react/nav/SideNav.js +4 -3
- package/dist/react/nav/SideNav.js.map +1 -1
- package/dist/react/nav/SideNavCustomize.d.ts.map +1 -1
- package/dist/react/nav/SideNavCustomize.js +2 -1
- package/dist/react/nav/SideNavCustomize.js.map +1 -1
- package/dist/react/palette/CommandPalette.d.ts.map +1 -1
- package/dist/react/palette/CommandPalette.js +3 -2
- package/dist/react/palette/CommandPalette.js.map +1 -1
- package/dist/server/drivers/pooledControlStores.pg.test.js +1 -0
- package/dist/server/drivers/pooledControlStores.pg.test.js.map +1 -1
- package/dist/server/drivers/pooledIdentityStore.pg.test.js +1 -0
- package/dist/server/drivers/pooledIdentityStore.pg.test.js.map +1 -1
- package/dist/server/drivers/retentionPolicy.pg.test.js +1 -0
- package/dist/server/drivers/retentionPolicy.pg.test.js.map +1 -1
- package/dist/server/guard/argon2Binding.d.ts +1 -1
- package/dist/server/guard/argon2Binding.js +1 -1
- package/dist/server/incidents/store.d.ts +3 -3
- package/dist/server/index.js +1 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/master-lock/masterLock.d.ts +1 -1
- package/dist/server/media-bun/index.js +1 -1
- package/dist/server/media-bun/index.js.map +1 -1
- package/dist/server/paths/appDataHome.d.ts +20 -0
- package/dist/server/paths/appDataHome.d.ts.map +1 -0
- package/dist/server/paths/appDataHome.js +69 -0
- package/dist/server/paths/appDataHome.js.map +1 -0
- package/dist/server/retention/archive.d.ts +3 -4
- package/dist/server/retention/archive.d.ts.map +1 -1
- package/dist/server/retention/archive.js +20 -15
- package/dist/server/retention/archive.js.map +1 -1
- package/dist/server/retention/index.d.ts +1 -1
- package/dist/server/retention/index.js +1 -1
- package/dist/server/retention/policy.d.ts +2 -2
- package/dist/server/retention/policy.d.ts.map +1 -1
- package/dist/server/retention/policy.js +1 -1
- package/dist/server/retention/store.d.ts.map +1 -1
- package/dist/server/retention/store.js +27 -20
- package/dist/server/retention/store.js.map +1 -1
- package/dist/server/runtime/localHost.d.ts +10 -5
- package/dist/server/runtime/localHost.d.ts.map +1 -1
- package/dist/server/runtime/localHost.js +12 -8
- package/dist/server/runtime/localHost.js.map +1 -1
- package/dist/server/runtime/meterRollup.pg.test.js +1 -0
- package/dist/server/runtime/meterRollup.pg.test.js.map +1 -1
- package/dist/server/runtime/recipe.d.ts +4 -4
- package/dist/server/runtime/retentionJob.pg.test.js +1 -0
- package/dist/server/runtime/retentionJob.pg.test.js.map +1 -1
- package/dist/server/search/pgSearchProvider.pg.test.js +1 -0
- package/dist/server/search/pgSearchProvider.pg.test.js.map +1 -1
- package/dist/shared/errors.d.ts +1 -1
- package/dist/shared/errors.js +1 -1
- package/dist/styles-static.css +391 -0
- package/dist/styles.css +27 -0
- package/package.json +19 -167
- package/scripts/generateStaticStyles.ts +122 -0
- package/scripts/publicSurface.ts +455 -0
- package/scripts/testTmpRoot.ts +34 -5
- package/src/client/index.ts +1 -1
- package/src/core/category/index.ts +2 -1
- package/src/core/category/types.ts +1 -1
- package/src/core/file-tree/fileTreeModel.spec.ts +134 -0
- package/src/core/file-tree/fileTreeModel.ts +104 -0
- package/src/core/layout/index.ts +1 -1
- package/src/core/media/index.ts +1 -1
- package/src/core/media/types.ts +1 -1
- package/src/core/media/uploadLimits.ts +1 -1
- package/src/core/sharing/model.ts +1 -1
- package/src/ctgr/index.ts +1 -1
- package/src/declaredDepsAreImported.spec.ts +87 -0
- package/src/demoFixture.spec.ts +133 -0
- package/src/index.ts +1 -1
- package/src/lockfileIsTracked.spec.ts +50 -0
- package/src/namedSubpathsResolve.spec.ts +119 -0
- package/src/publicSurface.spec.ts +72 -0
- package/src/react/activity-bar/ActivityBar.tsx +17 -0
- package/src/react/analytics/index.ts +1 -1
- package/src/react/chat/MessageComposer.tsx +5 -4
- package/src/react/components/Button.tsx +3 -2
- package/src/react/components/Checkbox.spec.tsx +51 -0
- package/src/react/components/Checkbox.tsx +68 -26
- package/src/react/components/CodeArea.tsx +2 -1
- package/src/react/components/CodeChip.spec.tsx +2 -2
- package/src/react/components/Collapsible.tsx +2 -1
- package/src/react/components/ComboboxField.tsx +3 -2
- package/src/react/components/CopyButton.tsx +2 -1
- package/src/react/components/CopyableText.spec.tsx +1 -1
- package/src/react/components/DataTable/ColumnChecklist.tsx +2 -1
- package/src/react/components/DataTable/Pagination.tsx +2 -1
- package/src/react/components/DataTable/SortHeader.tsx +2 -1
- package/src/react/components/DataTable/{FilterBuilder.tsx → TableFilterBuilder.tsx} +33 -5
- package/src/react/components/DataTable/Toolbar.tsx +3 -3
- package/src/react/components/DataTable/cells/LinkCell.tsx +2 -1
- package/src/react/components/DataTable/index.ts +8 -1
- package/src/react/components/DragHandle.tsx +2 -1
- package/src/react/components/EmojiField.tsx +2 -1
- package/src/react/components/EventTimeline.tsx +3 -2
- package/src/react/components/FileLocation.spec.tsx +1 -1
- package/src/react/components/IconButton.tsx +1 -1
- package/src/react/components/InfoHint.tsx +5 -4
- package/src/react/components/InheritBadge.tsx +1 -1
- package/src/react/components/InlineEditableText.tsx +2 -1
- package/src/react/components/MeterList.tsx +2 -1
- package/src/react/components/PathText.tsx +4 -3
- package/src/react/components/RatingField.tsx +2 -1
- package/src/react/components/SecretInput.tsx +3 -3
- package/src/react/components/SegmentedControl.tsx +2 -2
- package/src/react/components/StarRating.spec.tsx +2 -2
- package/src/react/components/StarRating.tsx +9 -5
- package/src/react/components/StatStrip.tsx +2 -1
- package/src/react/components/StatTile.tsx +3 -3
- package/src/react/components/Tabs.spec.tsx +3 -2
- package/src/react/components/Tabs.tsx +2 -1
- package/src/react/components/TruncatedText.tsx +2 -1
- package/src/react/components/calendar/MonthGrid.spec.tsx +2 -1
- package/src/react/components/calendar/MonthGrid.tsx +2 -1
- package/src/react/components/calendar/WeekView.tsx +2 -1
- package/src/react/components/revealOnHover.ts +3 -2
- package/src/react/file-tree/FileTree.spec.tsx +248 -0
- package/src/react/file-tree/FileTree.tsx +304 -4
- package/src/react/file-tree/fileTree.css +52 -0
- package/src/react/file-tree/fileTreeGeometry.fixture.json +151 -0
- package/src/react/file-tree/fileTreeGeometry.spec.ts +33 -52
- package/src/react/filter-rail/FilterRail.spec.tsx +2 -1
- package/src/react/filter-rail/FilterRail.tsx +5 -4
- package/src/react/folder-tree/FolderTreeRail.tsx +2 -1
- package/src/react/index.ts +13 -3
- package/src/react/layoutEngine/index.ts +1 -1
- package/src/react/layoutEngine/types.ts +1 -1
- package/src/react/lib/field.ts +4 -2
- package/src/react/lib/floatingStyles.spec.ts +2 -1
- package/src/react/lib/floatingStyles.ts +3 -1
- package/src/react/lib/tapTarget.ts +100 -0
- package/src/react/media/MaskPainter.tsx +2 -2
- package/src/react/media/VideoTrimmer.tsx +1 -1
- package/src/react/media/denseGallery.css +3 -3
- package/src/react/media/ffmpegWasm.ts +2 -2
- package/src/react/media/videoPlayer.css +42 -0
- package/src/react/namespace/NamespaceTargetCapsule.tsx +2 -2
- package/src/react/nav/BreadcrumbTrail.tsx +4 -3
- package/src/react/nav/HubTileGrid.tsx +2 -1
- package/src/react/nav/SideNav.tsx +4 -3
- package/src/react/nav/SideNavCustomize.tsx +2 -1
- package/src/react/palette/CommandPalette.tsx +3 -2
- package/src/server/ctgr.ts +1 -1
- package/src/server/drivers/pooledControlStores.pg.test.ts +1 -0
- package/src/server/drivers/pooledIdentityStore.pg.test.ts +1 -0
- package/src/server/drivers/retentionPolicy.pg.test.ts +1 -0
- package/src/server/guard/argon2Binding.ts +1 -1
- package/src/server/incidents/store.ts +3 -3
- package/src/server/index.ts +1 -1
- package/src/server/master-lock/masterLock.spec.ts +18 -2
- package/src/server/master-lock/masterLock.ts +1 -1
- package/src/server/media-bun/image.spec.ts +1 -0
- package/src/server/media-bun/index.ts +1 -1
- package/src/server/media-bun/video.spec.ts +1 -0
- package/src/server/paths/appDataHome.spec.ts +87 -0
- package/src/server/paths/appDataHome.ts +84 -0
- package/src/server/retention/archive.spec.ts +26 -4
- package/src/server/retention/archive.ts +20 -15
- package/src/server/retention/index.ts +1 -1
- package/src/server/retention/policy.ts +2 -2
- package/src/server/retention/store.spec.ts +38 -10
- package/src/server/retention/store.ts +26 -19
- package/src/server/runtime/localHost.spec.ts +22 -3
- package/src/server/runtime/localHost.ts +12 -9
- package/src/server/runtime/meterRollup.pg.test.ts +1 -0
- package/src/server/runtime/recipe.ts +4 -4
- package/src/server/runtime/retentionJob.pg.test.ts +1 -0
- package/src/server/search/pgSearchProvider.pg.test.ts +1 -0
- package/src/server/storage/binaryServerProcessing.integration.spec.ts +6 -2
- package/src/server/storage/chunked.integration.spec.ts +5 -2
- package/src/server/storage/fileUploadClient-chunked.integration.spec.ts +5 -2
- package/src/server/storage/files/adapter.photo.display.spec.ts +1 -0
- package/src/server/storage/imageThumbnail.spec.ts +1 -0
- package/src/server/storage/transcode.integration.spec.ts +5 -2
- package/src/server/storage/videoProcessor.posterOnly.spec.ts +1 -0
- package/src/shared/errors.ts +1 -1
- package/src/skippedTestsAreAnswered.spec.ts +215 -0
- package/src/styles-static.css +391 -0
- package/src/styles.css +27 -0
- package/src/stylesStaticMatches.spec.ts +134 -0
- package/src/tapTargetStylesheet.spec.ts +150 -0
- package/src/testTmpRoot.spec.ts +102 -0
- package/dist/core/duplicates/index.d.ts +0 -116
- package/dist/core/duplicates/index.d.ts.map +0 -1
- package/dist/core/duplicates/index.js +0 -178
- package/dist/core/duplicates/index.js.map +0 -1
- package/dist/core/namespace/helpers.d.ts +0 -14
- package/dist/core/namespace/helpers.d.ts.map +0 -1
- package/dist/core/namespace/helpers.js +0 -29
- package/dist/core/namespace/helpers.js.map +0 -1
- package/dist/core/namespace/index.d.ts +0 -4
- package/dist/core/namespace/index.d.ts.map +0 -1
- package/dist/core/namespace/index.js +0 -6
- package/dist/core/namespace/index.js.map +0 -1
- package/dist/core/namespace/memoryStore.d.ts +0 -19
- package/dist/core/namespace/memoryStore.d.ts.map +0 -1
- package/dist/core/namespace/memoryStore.js +0 -70
- package/dist/core/namespace/memoryStore.js.map +0 -1
- package/dist/core/namespace/types.d.ts +0 -44
- package/dist/core/namespace/types.d.ts.map +0 -1
- package/dist/core/namespace/types.js +0 -8
- package/dist/core/namespace/types.js.map +0 -1
- package/dist/game/core/DisposeRegistry.d.ts +0 -42
- package/dist/game/core/DisposeRegistry.d.ts.map +0 -1
- package/dist/game/core/DisposeRegistry.js +0 -67
- package/dist/game/core/DisposeRegistry.js.map +0 -1
- package/dist/game/core/drawBudget.d.ts +0 -26
- package/dist/game/core/drawBudget.d.ts.map +0 -1
- package/dist/game/core/drawBudget.js +0 -55
- package/dist/game/core/drawBudget.js.map +0 -1
- package/dist/game/core/fixedTimestep.d.ts +0 -38
- package/dist/game/core/fixedTimestep.d.ts.map +0 -1
- package/dist/game/core/fixedTimestep.js +0 -47
- package/dist/game/core/fixedTimestep.js.map +0 -1
- package/dist/game/core/index.d.ts +0 -9
- package/dist/game/core/index.d.ts.map +0 -1
- package/dist/game/core/index.js +0 -8
- package/dist/game/core/index.js.map +0 -1
- package/dist/game/core/inputCollector.d.ts +0 -82
- package/dist/game/core/inputCollector.d.ts.map +0 -1
- package/dist/game/core/inputCollector.js +0 -176
- package/dist/game/core/inputCollector.js.map +0 -1
- package/dist/game/core/resizeCanvas.d.ts +0 -19
- package/dist/game/core/resizeCanvas.d.ts.map +0 -1
- package/dist/game/core/resizeCanvas.js +0 -29
- package/dist/game/core/resizeCanvas.js.map +0 -1
- package/dist/game/react/index.d.ts +0 -3
- package/dist/game/react/index.d.ts.map +0 -1
- package/dist/game/react/index.js +0 -5
- package/dist/game/react/index.js.map +0 -1
- package/dist/game/react/useGameEngine.d.ts +0 -64
- package/dist/game/react/useGameEngine.d.ts.map +0 -1
- package/dist/game/react/useGameEngine.js +0 -78
- package/dist/game/react/useGameEngine.js.map +0 -1
- package/dist/react/canvas/CanvasNavHUD.d.ts +0 -64
- package/dist/react/canvas/CanvasNavHUD.d.ts.map +0 -1
- package/dist/react/canvas/CanvasNavHUD.js +0 -58
- package/dist/react/canvas/CanvasNavHUD.js.map +0 -1
- package/dist/react/canvas/fitLabel.d.ts +0 -53
- package/dist/react/canvas/fitLabel.d.ts.map +0 -1
- package/dist/react/canvas/fitLabel.js +0 -104
- package/dist/react/canvas/fitLabel.js.map +0 -1
- package/dist/react/canvas/index.d.ts +0 -4
- package/dist/react/canvas/index.d.ts.map +0 -1
- package/dist/react/canvas/index.js +0 -4
- package/dist/react/canvas/index.js.map +0 -1
- package/dist/react/canvas/lod.d.ts +0 -40
- package/dist/react/canvas/lod.d.ts.map +0 -1
- package/dist/react/canvas/lod.js +0 -37
- package/dist/react/canvas/lod.js.map +0 -1
- package/dist/react/components/DataTable/FilterBuilder.d.ts +0 -38
- package/dist/react/components/DataTable/FilterBuilder.d.ts.map +0 -1
- package/dist/react/components/DataTable/FilterBuilder.js.map +0 -1
- package/dist/react/seo/HeadProvider.d.ts +0 -14
- package/dist/react/seo/HeadProvider.d.ts.map +0 -1
- package/dist/react/seo/HeadProvider.js +0 -44
- package/dist/react/seo/HeadProvider.js.map +0 -1
- package/dist/react/seo/applyHeadToDocument.d.ts +0 -3
- package/dist/react/seo/applyHeadToDocument.d.ts.map +0 -1
- package/dist/react/seo/applyHeadToDocument.js +0 -66
- package/dist/react/seo/applyHeadToDocument.js.map +0 -1
- package/dist/react/seo/index.d.ts +0 -3
- package/dist/react/seo/index.d.ts.map +0 -1
- package/dist/react/seo/index.js +0 -7
- package/dist/react/seo/index.js.map +0 -1
- package/dist/react/timeline/ClipView.d.ts +0 -29
- package/dist/react/timeline/ClipView.d.ts.map +0 -1
- package/dist/react/timeline/ClipView.js +0 -53
- package/dist/react/timeline/ClipView.js.map +0 -1
- package/dist/react/timeline/Playhead.d.ts +0 -16
- package/dist/react/timeline/Playhead.d.ts.map +0 -1
- package/dist/react/timeline/Playhead.js +0 -26
- package/dist/react/timeline/Playhead.js.map +0 -1
- package/dist/react/timeline/TimeRuler.d.ts +0 -21
- package/dist/react/timeline/TimeRuler.d.ts.map +0 -1
- package/dist/react/timeline/TimeRuler.js +0 -31
- package/dist/react/timeline/TimeRuler.js.map +0 -1
- package/dist/react/timeline/TimelineSurface.d.ts +0 -29
- package/dist/react/timeline/TimelineSurface.d.ts.map +0 -1
- package/dist/react/timeline/TimelineSurface.js +0 -56
- package/dist/react/timeline/TimelineSurface.js.map +0 -1
- package/dist/react/timeline/TrackLane.d.ts +0 -31
- package/dist/react/timeline/TrackLane.d.ts.map +0 -1
- package/dist/react/timeline/TrackLane.js +0 -32
- package/dist/react/timeline/TrackLane.js.map +0 -1
- package/dist/react/timeline/index.d.ts +0 -6
- package/dist/react/timeline/index.d.ts.map +0 -1
- package/dist/react/timeline/index.js +0 -12
- package/dist/react/timeline/index.js.map +0 -1
- package/dist/server/private-media/index.d.ts +0 -7
- package/dist/server/private-media/index.d.ts.map +0 -1
- package/dist/server/private-media/index.js +0 -13
- package/dist/server/private-media/index.js.map +0 -1
- package/dist/server/seo/index.d.ts +0 -3
- package/dist/server/seo/index.d.ts.map +0 -1
- package/dist/server/seo/index.js +0 -6
- package/dist/server/seo/index.js.map +0 -1
- package/dist/server/seo/mountSeoRoutes.d.ts +0 -9
- package/dist/server/seo/mountSeoRoutes.d.ts.map +0 -1
- package/dist/server/seo/mountSeoRoutes.js +0 -19
- package/dist/server/seo/mountSeoRoutes.js.map +0 -1
- package/dist/server/seo/serveHeadInjectedIndex.d.ts +0 -9
- package/dist/server/seo/serveHeadInjectedIndex.d.ts.map +0 -1
- package/dist/server/seo/serveHeadInjectedIndex.js +0 -20
- package/dist/server/seo/serveHeadInjectedIndex.js.map +0 -1
- package/dist/upload.d.ts +0 -148
- package/dist/upload.d.ts.map +0 -1
- package/dist/upload.js +0 -159
- package/dist/upload.js.map +0 -1
- package/dist/verify/runtime/index.d.ts +0 -16
- package/dist/verify/runtime/index.d.ts.map +0 -1
- package/dist/verify/runtime/index.js +0 -16
- package/dist/verify/runtime/index.js.map +0 -1
- package/scripts/demoCheck.ts +0 -42
- package/src/core/duplicates/index.spec.ts +0 -116
- package/src/core/duplicates/index.ts +0 -203
- package/src/core/namespace/helpers.ts +0 -31
- package/src/core/namespace/index.ts +0 -12
- package/src/core/namespace/memoryStore.ts +0 -77
- package/src/core/namespace/namespace.spec.ts +0 -117
- package/src/core/namespace/types.ts +0 -53
- package/src/game/core/DisposeRegistry.spec.ts +0 -53
- package/src/game/core/DisposeRegistry.ts +0 -70
- package/src/game/core/drawBudget.spec.ts +0 -51
- package/src/game/core/drawBudget.ts +0 -75
- package/src/game/core/fixedTimestep.spec.ts +0 -91
- package/src/game/core/fixedTimestep.ts +0 -79
- package/src/game/core/index.ts +0 -16
- package/src/game/core/inputCollector.spec.ts +0 -29
- package/src/game/core/inputCollector.ts +0 -245
- package/src/game/core/resizeCanvas.ts +0 -31
- package/src/game/react/index.ts +0 -10
- package/src/game/react/useGameEngine.ts +0 -125
- package/src/react/canvas/CanvasNavHUD.spec.tsx +0 -62
- package/src/react/canvas/CanvasNavHUD.tsx +0 -210
- package/src/react/canvas/fitLabel.spec.ts +0 -82
- package/src/react/canvas/fitLabel.ts +0 -150
- package/src/react/canvas/index.ts +0 -15
- package/src/react/canvas/lod.ts +0 -53
- package/src/react/seo/HeadProvider.tsx +0 -67
- package/src/react/seo/applyHeadToDocument.ts +0 -73
- package/src/react/seo/index.ts +0 -12
- package/src/react/seo/seo.spec.tsx +0 -101
- package/src/react/timeline/ClipView.tsx +0 -146
- package/src/react/timeline/Playhead.tsx +0 -63
- package/src/react/timeline/TimeRuler.tsx +0 -85
- package/src/react/timeline/TimelineSurface.tsx +0 -157
- package/src/react/timeline/TrackLane.tsx +0 -87
- package/src/react/timeline/index.ts +0 -12
- package/src/react/timeline/timeline.spec.tsx +0 -175
- package/src/server/private-media/index.ts +0 -45
- package/src/server/seo/index.ts +0 -8
- package/src/server/seo/mountSeoRoutes.ts +0 -37
- package/src/server/seo/seo.spec.ts +0 -128
- package/src/server/seo/serveHeadInjectedIndex.ts +0 -36
- package/src/upload.spec.ts +0 -300
- package/src/upload.ts +0 -288
- package/src/verify/runtime/index.ts +0 -64
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
import { afterEach, describe, expect, test } from 'bun:test';
|
|
2
|
-
import { cleanup, createEvent, fireEvent, render } from '@testing-library/react';
|
|
3
|
-
import type { TimelineClip, TimelineTrack } from 'cwip/timeline';
|
|
4
|
-
import { ClipView } from './ClipView';
|
|
5
|
-
import { TimelineSurface } from './TimelineSurface';
|
|
6
|
-
import { TimeRuler } from './TimeRuler';
|
|
7
|
-
import { TrackLane } from './TrackLane';
|
|
8
|
-
|
|
9
|
-
afterEach(cleanup);
|
|
10
|
-
|
|
11
|
-
const clip = (partial: Partial<TimelineClip> & { id: string }): TimelineClip => ({
|
|
12
|
-
name: partial.id,
|
|
13
|
-
sourceAssetId: 'a1',
|
|
14
|
-
trackIn: 0,
|
|
15
|
-
trackOut: 10,
|
|
16
|
-
timelineStart: 0,
|
|
17
|
-
timelineEnd: 10,
|
|
18
|
-
speed: 1,
|
|
19
|
-
volume: 1,
|
|
20
|
-
...partial,
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
const track = (
|
|
24
|
-
id: string,
|
|
25
|
-
clips: TimelineClip[] = [],
|
|
26
|
-
type: 'video' | 'audio' = 'video',
|
|
27
|
-
): TimelineTrack => ({
|
|
28
|
-
id,
|
|
29
|
-
name: id,
|
|
30
|
-
type,
|
|
31
|
-
clips,
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
const noopClipHandlers = {
|
|
35
|
-
onSelect: () => {},
|
|
36
|
-
onMovePreview: () => {},
|
|
37
|
-
onMoveCommit: () => {},
|
|
38
|
-
onTrimPreview: () => {},
|
|
39
|
-
onTrimCommit: () => {},
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
describe('ClipView', () => {
|
|
43
|
-
test('positions by timeline seconds × zoom and shows name + source window', () => {
|
|
44
|
-
const c = clip({ id: 'intro', timelineStart: 2, timelineEnd: 6, trackIn: 1, trackOut: 5 });
|
|
45
|
-
const { getByRole, getByText } = render(
|
|
46
|
-
<ClipView clip={c} zoomScale={25} selected={false} {...noopClipHandlers} />,
|
|
47
|
-
);
|
|
48
|
-
const block = getByRole('button', { name: 'Clip intro' });
|
|
49
|
-
expect(block.style.left).toBe('50px');
|
|
50
|
-
expect(block.style.width).toBe('98px'); // 100px minus the 2px seam
|
|
51
|
-
expect(getByText('intro')).toBeDefined();
|
|
52
|
-
expect(getByText('0:01–0:05')).toBeDefined();
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
test('click selects (and stops at the clip, not the lane behind)', () => {
|
|
56
|
-
let selected = 0;
|
|
57
|
-
let laneClicks = 0;
|
|
58
|
-
const { getByRole } = render(
|
|
59
|
-
<TrackLane
|
|
60
|
-
track={track('v1')}
|
|
61
|
-
zoomScale={25}
|
|
62
|
-
durationSeconds={20}
|
|
63
|
-
onRunwayClick={() => {
|
|
64
|
-
laneClicks += 1;
|
|
65
|
-
}}
|
|
66
|
-
>
|
|
67
|
-
<ClipView
|
|
68
|
-
clip={clip({ id: 'c1' })}
|
|
69
|
-
zoomScale={25}
|
|
70
|
-
selected={false}
|
|
71
|
-
{...noopClipHandlers}
|
|
72
|
-
onSelect={() => {
|
|
73
|
-
selected += 1;
|
|
74
|
-
}}
|
|
75
|
-
/>
|
|
76
|
-
</TrackLane>,
|
|
77
|
-
);
|
|
78
|
-
fireEvent.click(getByRole('button', { name: 'Clip c1' }));
|
|
79
|
-
expect(selected).toBe(1);
|
|
80
|
-
expect(laneClicks).toBe(0);
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
test('shows a speed badge only when speed ≠ 1', () => {
|
|
84
|
-
const { queryByText, rerender } = render(
|
|
85
|
-
<ClipView clip={clip({ id: 'c1' })} zoomScale={25} selected={false} {...noopClipHandlers} />,
|
|
86
|
-
);
|
|
87
|
-
expect(queryByText('1x')).toBeNull();
|
|
88
|
-
rerender(
|
|
89
|
-
<ClipView
|
|
90
|
-
clip={clip({ id: 'c1', speed: 2, timelineEnd: 5 })}
|
|
91
|
-
zoomScale={25}
|
|
92
|
-
selected={false}
|
|
93
|
-
{...noopClipHandlers}
|
|
94
|
-
/>,
|
|
95
|
-
);
|
|
96
|
-
expect(queryByText('2x')).toBeDefined();
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
describe('TimeRuler', () => {
|
|
101
|
-
test('thins tick labels as zoom drops', () => {
|
|
102
|
-
const dense = render(<TimeRuler durationSeconds={10} zoomScale={100} onScrub={() => {}} />);
|
|
103
|
-
// 100 px/s → 1s ticks: 0..10 = 11 labels
|
|
104
|
-
expect(dense.container.querySelectorAll('span').length).toBe(11);
|
|
105
|
-
dense.unmount();
|
|
106
|
-
const sparse = render(<TimeRuler durationSeconds={10} zoomScale={10} onScrub={() => {}} />);
|
|
107
|
-
// 10 px/s → 10s ticks: 0, 10
|
|
108
|
-
expect(sparse.container.querySelectorAll('span').length).toBe(2);
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
describe('TrackLane', () => {
|
|
113
|
-
test('reports drops in seconds using the runway rect and zoom', () => {
|
|
114
|
-
let dropped: { atSeconds: number } | null = null;
|
|
115
|
-
const { container } = render(
|
|
116
|
-
<TrackLane
|
|
117
|
-
track={track('v1')}
|
|
118
|
-
zoomScale={25}
|
|
119
|
-
durationSeconds={20}
|
|
120
|
-
onDropData={(payload) => {
|
|
121
|
-
dropped = payload;
|
|
122
|
-
}}
|
|
123
|
-
>
|
|
124
|
-
<div />
|
|
125
|
-
</TrackLane>,
|
|
126
|
-
);
|
|
127
|
-
const runway = container.querySelector('[data-track-id="v1"]') as HTMLElement;
|
|
128
|
-
runway.getBoundingClientRect = () =>
|
|
129
|
-
({
|
|
130
|
-
left: 100,
|
|
131
|
-
top: 0,
|
|
132
|
-
width: 500,
|
|
133
|
-
height: 64,
|
|
134
|
-
right: 600,
|
|
135
|
-
bottom: 64,
|
|
136
|
-
x: 100,
|
|
137
|
-
y: 0,
|
|
138
|
-
}) as DOMRect;
|
|
139
|
-
// happy-dom's DragEvent constructor ignores mouse-init fields — set them directly
|
|
140
|
-
const drop = createEvent.drop(runway);
|
|
141
|
-
Object.defineProperty(drop, 'clientX', { value: 200 });
|
|
142
|
-
Object.defineProperty(drop, 'dataTransfer', { value: { getData: () => '' } });
|
|
143
|
-
fireEvent(runway, drop);
|
|
144
|
-
expect(dropped).not.toBeNull();
|
|
145
|
-
expect((dropped as unknown as { atSeconds: number }).atSeconds).toBe(4); // (200-100)/25
|
|
146
|
-
});
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
describe('TimelineSurface', () => {
|
|
150
|
-
test('renders ruler, lanes, playhead, and zoom controls together', () => {
|
|
151
|
-
const tracks = [track('v1', [clip({ id: 'c1' })]), track('a1', [], 'audio')];
|
|
152
|
-
const { getByRole, getAllByRole, getByText } = render(
|
|
153
|
-
<TimelineSurface
|
|
154
|
-
tracks={tracks}
|
|
155
|
-
zoomScale={25}
|
|
156
|
-
currentTime={3}
|
|
157
|
-
onScrub={() => {}}
|
|
158
|
-
onZoomChange={() => {}}
|
|
159
|
-
renderTrack={(t, duration) => (
|
|
160
|
-
<TrackLane key={t.id} track={t} zoomScale={25} durationSeconds={duration}>
|
|
161
|
-
{t.clips.map((c) => (
|
|
162
|
-
<ClipView key={c.id} clip={c} zoomScale={25} selected={false} {...noopClipHandlers} />
|
|
163
|
-
))}
|
|
164
|
-
</TrackLane>
|
|
165
|
-
)}
|
|
166
|
-
/>,
|
|
167
|
-
);
|
|
168
|
-
expect(getByRole('slider', { name: 'Timeline position' })).toBeDefined();
|
|
169
|
-
expect(getByRole('slider', { name: 'Playhead' })).toBeDefined();
|
|
170
|
-
expect(getByRole('button', { name: 'Zoom in' })).toBeDefined();
|
|
171
|
-
expect(getByText('v1')).toBeDefined();
|
|
172
|
-
expect(getByText('a1')).toBeDefined();
|
|
173
|
-
expect(getAllByRole('button', { name: 'Clip c1' })).toHaveLength(1);
|
|
174
|
-
});
|
|
175
|
-
});
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
// cursedbelt/server/private-media — encrypted private media: a multi-password, semi-deniable
|
|
2
|
-
// layer over server/storage. Bytes are AES-128-encrypted HLS (fast, edge-cacheable, client-
|
|
3
|
-
// decrypted); the per-item content key is wrapped under a set key that is either server-held
|
|
4
|
-
// (standard, recoverable) or password-derived (deniable, zero-knowledge). A clear index exposes
|
|
5
|
-
// only size + created-at so users can prune forgotten-password media; title/thumb/notes stay in
|
|
6
|
-
// an encrypted envelope revealed only by the right password. Builds on cwip secretBox (scrypt +
|
|
7
|
-
// AES-GCM) + server/auth (jose) + server/media (the encrypted-HLS pipeline).
|
|
8
|
-
|
|
9
|
-
export type { ContentKey, KeyMode } from './crypto';
|
|
10
|
-
export {
|
|
11
|
-
cryptBlobStream,
|
|
12
|
-
derivePasswordSetKey,
|
|
13
|
-
deriveServerSetKey,
|
|
14
|
-
generateContentKey,
|
|
15
|
-
generateUserSalt,
|
|
16
|
-
openMeta,
|
|
17
|
-
sealMeta,
|
|
18
|
-
unwrapContentKey,
|
|
19
|
-
wrapContentKey,
|
|
20
|
-
} from './crypto';
|
|
21
|
-
export {
|
|
22
|
-
createMemoryPrivateIndex,
|
|
23
|
-
type PrivateIndex,
|
|
24
|
-
type PrivateIndexRow,
|
|
25
|
-
type PrivateItem,
|
|
26
|
-
toPublic,
|
|
27
|
-
} from './index-store';
|
|
28
|
-
export {
|
|
29
|
-
type CorsResolver,
|
|
30
|
-
type MountPrivateOptions,
|
|
31
|
-
mountPrivateRoutes,
|
|
32
|
-
} from './mountPrivateRoutes';
|
|
33
|
-
export {
|
|
34
|
-
type PrivateBlobResult,
|
|
35
|
-
type PrivateProcessOptions,
|
|
36
|
-
type PrivateProcessResult,
|
|
37
|
-
processPrivateBlob,
|
|
38
|
-
processPrivateVideo,
|
|
39
|
-
} from './pipeline';
|
|
40
|
-
export {
|
|
41
|
-
createUnlockService,
|
|
42
|
-
type UnlockGrant,
|
|
43
|
-
type UnlockPasswordPolicy,
|
|
44
|
-
type UnlockService,
|
|
45
|
-
} from './unlock';
|
package/src/server/seo/index.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
// cursedbelt/server/seo — Hono wiring for cwip's SEO core: sitemap.xml/robots.txt
|
|
2
|
-
// routes and a static-HTML head-injection handler. See seo-reusable-plan.md for the
|
|
3
|
-
// wider architecture (visibility model, delivery targets, cursedshell aggregation).
|
|
4
|
-
export { type MountSeoOptions, mountSeoRoutes } from './mountSeoRoutes';
|
|
5
|
-
export {
|
|
6
|
-
type ServeHeadInjectedIndexOptions,
|
|
7
|
-
serveHeadInjectedIndex,
|
|
8
|
-
} from './serveHeadInjectedIndex';
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import type { SeoPolicy } from 'cwip/seo';
|
|
2
|
-
import { buildRobots, buildSitemap } from 'cwip/seo';
|
|
3
|
-
import type { Hono } from 'hono';
|
|
4
|
-
|
|
5
|
-
export interface MountSeoOptions {
|
|
6
|
-
// Path the sitemap is served at (default '/sitemap.xml'); also what buildRobots
|
|
7
|
-
// points its `Sitemap:` line at.
|
|
8
|
-
sitemapPath?: string;
|
|
9
|
-
// Path robots.txt is served at (default '/robots.txt').
|
|
10
|
-
robotsPath?: string;
|
|
11
|
-
// Cache-Control header applied to both responses (default 'public, max-age=3600').
|
|
12
|
-
cacheControl?: string;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
// Registers GET /sitemap.xml and GET /robots.txt from a SeoPolicy. These serve raw
|
|
16
|
-
// text bytes, so — per cursedbelt STANDARDS.md §5 — they are registered DIRECTLY
|
|
17
|
-
// with `app.get`, never through `buildRoutes`: routing them through the ctgr
|
|
18
|
-
// GET-tunnel would base64url-encode the response body instead of serving it as-is.
|
|
19
|
-
export const mountSeoRoutes = (
|
|
20
|
-
app: Hono,
|
|
21
|
-
policy: SeoPolicy,
|
|
22
|
-
options: MountSeoOptions = {},
|
|
23
|
-
): void => {
|
|
24
|
-
const sitemapPath = options.sitemapPath ?? '/sitemap.xml';
|
|
25
|
-
const robotsPath = options.robotsPath ?? '/robots.txt';
|
|
26
|
-
const cacheControl = options.cacheControl ?? 'public, max-age=3600';
|
|
27
|
-
|
|
28
|
-
app.get(sitemapPath, (c) => {
|
|
29
|
-
c.header('Cache-Control', cacheControl);
|
|
30
|
-
return c.body(buildSitemap(policy), 200, { 'Content-Type': 'application/xml' });
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
app.get(robotsPath, (c) => {
|
|
34
|
-
c.header('Cache-Control', cacheControl);
|
|
35
|
-
return c.body(buildRobots(policy, { sitemapPath }), 200, { 'Content-Type': 'text/plain' });
|
|
36
|
-
});
|
|
37
|
-
};
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from 'bun:test';
|
|
2
|
-
import type { SeoPolicy } from 'cwip/seo';
|
|
3
|
-
import { Hono } from 'hono';
|
|
4
|
-
import { mountSeoRoutes } from './mountSeoRoutes';
|
|
5
|
-
import { serveHeadInjectedIndex } from './serveHeadInjectedIndex';
|
|
6
|
-
|
|
7
|
-
const policy: SeoPolicy = {
|
|
8
|
-
siteUrl: 'https://example.com',
|
|
9
|
-
defaultVisibility: 'private',
|
|
10
|
-
disallow: ['/api'],
|
|
11
|
-
entries: [
|
|
12
|
-
{
|
|
13
|
-
path: '/',
|
|
14
|
-
visibility: 'public',
|
|
15
|
-
head: { title: 'Home', description: 'Welcome' },
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
path: '/articles/free-monads',
|
|
19
|
-
visibility: 'public',
|
|
20
|
-
head: {
|
|
21
|
-
title: 'Free monads',
|
|
22
|
-
description: 'An article about free monads',
|
|
23
|
-
openGraph: { type: 'article' },
|
|
24
|
-
},
|
|
25
|
-
lastmod: '2026-01-01',
|
|
26
|
-
},
|
|
27
|
-
{ path: '/notes', visibility: 'private' },
|
|
28
|
-
],
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
describe('mountSeoRoutes', () => {
|
|
32
|
-
test('serves sitemap.xml with public entries and the right content-type', async () => {
|
|
33
|
-
const app = new Hono();
|
|
34
|
-
mountSeoRoutes(app, policy);
|
|
35
|
-
const res = await app.request('/sitemap.xml');
|
|
36
|
-
expect(res.status).toBe(200);
|
|
37
|
-
expect(res.headers.get('Content-Type')).toContain('application/xml');
|
|
38
|
-
const body = await res.text();
|
|
39
|
-
expect(body).toContain('<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">');
|
|
40
|
-
expect(body).toContain('https://example.com/articles/free-monads');
|
|
41
|
-
expect(body).not.toContain('/notes');
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
test('serves robots.txt disallowing private entries and explicit paths', async () => {
|
|
45
|
-
const app = new Hono();
|
|
46
|
-
mountSeoRoutes(app, policy);
|
|
47
|
-
const res = await app.request('/robots.txt');
|
|
48
|
-
expect(res.status).toBe(200);
|
|
49
|
-
expect(res.headers.get('Content-Type')).toContain('text/plain');
|
|
50
|
-
const body = await res.text();
|
|
51
|
-
expect(body).toContain('Disallow: /api');
|
|
52
|
-
expect(body).toContain('Disallow: /notes');
|
|
53
|
-
expect(body).toContain('Sitemap: https://example.com/sitemap.xml');
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
test('honors custom sitemapPath/robotsPath/cacheControl', async () => {
|
|
57
|
-
const app = new Hono();
|
|
58
|
-
mountSeoRoutes(app, policy, {
|
|
59
|
-
sitemapPath: '/custom-sitemap.xml',
|
|
60
|
-
robotsPath: '/custom-robots.txt',
|
|
61
|
-
cacheControl: 'no-cache',
|
|
62
|
-
});
|
|
63
|
-
const sitemap = await app.request('/custom-sitemap.xml');
|
|
64
|
-
const robots = await app.request('/custom-robots.txt');
|
|
65
|
-
expect(sitemap.status).toBe(200);
|
|
66
|
-
expect(sitemap.headers.get('Cache-Control')).toBe('no-cache');
|
|
67
|
-
expect(robots.status).toBe(200);
|
|
68
|
-
expect(await robots.text()).toContain('Sitemap: https://example.com/custom-sitemap.xml');
|
|
69
|
-
});
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
const baseHtml = `<!doctype html>
|
|
73
|
-
<html>
|
|
74
|
-
<head>
|
|
75
|
-
<title>Base Title</title>
|
|
76
|
-
<meta name="description" content="Base description">
|
|
77
|
-
</head>
|
|
78
|
-
<body><div id="root"></div></body>
|
|
79
|
-
</html>
|
|
80
|
-
`;
|
|
81
|
-
|
|
82
|
-
describe('serveHeadInjectedIndex', () => {
|
|
83
|
-
test('injects the resolved head and strips the base title/description for a mapped path', async () => {
|
|
84
|
-
const app = new Hono();
|
|
85
|
-
app.get('*', (c) =>
|
|
86
|
-
serveHeadInjectedIndex({
|
|
87
|
-
html: baseHtml,
|
|
88
|
-
resolve: (path) =>
|
|
89
|
-
path === '/articles/free-monads'
|
|
90
|
-
? { title: 'Free monads', description: 'An article about free monads' }
|
|
91
|
-
: undefined,
|
|
92
|
-
})(c),
|
|
93
|
-
);
|
|
94
|
-
const res = await app.request('/articles/free-monads');
|
|
95
|
-
const body = await res.text();
|
|
96
|
-
expect(body).toContain('<title data-cwip-seo>Free monads</title>');
|
|
97
|
-
expect(body).toContain('An article about free monads');
|
|
98
|
-
expect(body).not.toContain('Base Title');
|
|
99
|
-
expect(body).not.toContain('Base description');
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
test('serves the base shell untouched for an unmapped path', async () => {
|
|
103
|
-
const app = new Hono();
|
|
104
|
-
app.get('*', (c) =>
|
|
105
|
-
serveHeadInjectedIndex({
|
|
106
|
-
html: baseHtml,
|
|
107
|
-
resolve: () => undefined,
|
|
108
|
-
})(c),
|
|
109
|
-
);
|
|
110
|
-
const res = await app.request('/some/authorized/path');
|
|
111
|
-
const body = await res.text();
|
|
112
|
-
expect(body).toContain('<title>Base Title</title>');
|
|
113
|
-
expect(body).toContain('Base description');
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
test('accepts an async html loader', async () => {
|
|
117
|
-
const app = new Hono();
|
|
118
|
-
app.get('*', (c) =>
|
|
119
|
-
serveHeadInjectedIndex({
|
|
120
|
-
html: async () => baseHtml,
|
|
121
|
-
resolve: () => ({ title: 'Loaded' }),
|
|
122
|
-
})(c),
|
|
123
|
-
);
|
|
124
|
-
const res = await app.request('/');
|
|
125
|
-
const body = await res.text();
|
|
126
|
-
expect(body).toContain('Loaded');
|
|
127
|
-
});
|
|
128
|
-
});
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import type { HeadModel } from 'cwip/seo';
|
|
2
|
-
import { injectHead, renderHead, stripBaseTitleAndDescription } from 'cwip/seo';
|
|
3
|
-
import type { Context } from 'hono';
|
|
4
|
-
|
|
5
|
-
export interface ServeHeadInjectedIndexOptions {
|
|
6
|
-
// The SPA's index.html, or a (possibly async) loader for it — read once per
|
|
7
|
-
// request so a caller can hot-reload the file in dev without restarting.
|
|
8
|
-
html: string | (() => string | Promise<string>);
|
|
9
|
-
// Looks up the HeadModel for a request path; return undefined to serve the base
|
|
10
|
-
// shell untouched (no injection) for an unmapped route.
|
|
11
|
-
resolve: (path: string) => HeadModel | undefined;
|
|
12
|
-
// Strip the base <title>/<meta name="description"> out of the shell before
|
|
13
|
-
// injecting the route's own (default true) — otherwise the shell's baseline
|
|
14
|
-
// title/description would sit alongside the injected ones.
|
|
15
|
-
stripBase?: boolean;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// Builds a Hono handler that serves `opts.html` with a per-route HeadModel spliced
|
|
19
|
-
// into <head> via cwip's `injectHead`/`renderHead` — a pure string transform, so it
|
|
20
|
-
// runs anywhere Bun does (this repo's Hono/Bun.serve host). An HTMLRewriter-based
|
|
21
|
-
// streaming variant for Cloudflare Workers/Pages Functions can reuse the exact same
|
|
22
|
-
// `renderHead` output later; that seam is intentionally left for a future target
|
|
23
|
-
// rather than built here (see seo-reusable-plan.md §4/§6).
|
|
24
|
-
export const serveHeadInjectedIndex = (opts: ServeHeadInjectedIndexOptions) => {
|
|
25
|
-
const stripBase = opts.stripBase ?? true;
|
|
26
|
-
|
|
27
|
-
return async (c: Context) => {
|
|
28
|
-
const html = typeof opts.html === 'function' ? await opts.html() : opts.html;
|
|
29
|
-
const model = opts.resolve(c.req.path);
|
|
30
|
-
if (!model) return c.html(html);
|
|
31
|
-
|
|
32
|
-
const shell = stripBase ? stripBaseTitleAndDescription(html) : html;
|
|
33
|
-
const headHtml = renderHead(model, { marker: true, indent: ' ' });
|
|
34
|
-
return c.html(injectHead(shell, headHtml));
|
|
35
|
-
};
|
|
36
|
-
};
|