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
|
@@ -27,15 +27,22 @@
|
|
|
27
27
|
* back up, copy to a box, or read at a glance.
|
|
28
28
|
*
|
|
29
29
|
* ── Where it lives ──────────────────────────────────────────────────────────
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* the
|
|
30
|
+
* `<app-data-home>/retention` — one root shared by every local app, so the
|
|
31
|
+
* station sees one fleet. The home is CONFIGURATION ({@link resolveAppDataHome}):
|
|
32
|
+
* `$APP_DATA_HOME` when a machine keeps every app's data under one root, else the
|
|
33
|
+
* OS's own convention (`$XDG_DATA_HOME`, `~/Library/Application Support`).
|
|
34
|
+
*
|
|
35
|
+
* 🔴 It was `~/<a private dotfolder>` until 2026-09-13, hardcoded, in a PUBLISHED
|
|
36
|
+
* package — so anyone who installed cursedbelt got a library hunting for one
|
|
37
|
+
* person's directory layout. A library may know what its caller told it and what
|
|
38
|
+
* the OS says; it may not know the name of a folder in somebody's home.
|
|
39
|
+
*
|
|
40
|
+
* A deployed box under `ProtectSystem=strict` has only its own data dir writable,
|
|
41
|
+
* so it falls back to `$APP_DATA_DIR/retention`: the app still sweeps on the same
|
|
42
|
+
* code and the same defaults, and a station instance on that box reads that box's
|
|
43
|
+
* fleet. The resolution probes WRITABILITY rather than assuming, because the
|
|
44
|
+
* failure it prevents — an app whose every publish silently EROFS-es — is
|
|
45
|
+
* invisible until someone asks why the UI is empty.
|
|
39
46
|
*/
|
|
40
47
|
import {
|
|
41
48
|
existsSync,
|
|
@@ -46,8 +53,8 @@ import {
|
|
|
46
53
|
rmSync,
|
|
47
54
|
writeFileSync,
|
|
48
55
|
} from "node:fs";
|
|
49
|
-
import { homedir } from "node:os";
|
|
50
56
|
import { join } from "node:path";
|
|
57
|
+
import { APP_DATA_HOME_ENV, resolveAppDataHome } from "../paths/appDataHome";
|
|
51
58
|
import type { RetentionDeclaration, RetentionOverride } from "./policy";
|
|
52
59
|
import { retentionKey } from "./policy";
|
|
53
60
|
|
|
@@ -155,15 +162,15 @@ export function resolveRetentionHome(
|
|
|
155
162
|
if (cachedHome) return cachedHome;
|
|
156
163
|
const candidates: string[] = [];
|
|
157
164
|
if (env.RETENTION_HOME) candidates.push(env.RETENTION_HOME);
|
|
158
|
-
|
|
159
|
-
//
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
const conventional =
|
|
163
|
-
//
|
|
164
|
-
// creating it would either fail (read-only namespace) or strand a
|
|
165
|
-
// somewhere no station instance looks.
|
|
166
|
-
if (existsSync(conventional)) candidates.push(join(conventional, "retention"));
|
|
165
|
+
// An explicitly CONFIGURED home is used whether or not it exists yet — the
|
|
166
|
+
// operator naming it is the statement that it is the right place.
|
|
167
|
+
const configured = env[APP_DATA_HOME_ENV]?.trim();
|
|
168
|
+
if (configured) candidates.push(join(configured, "retention"));
|
|
169
|
+
const conventional = resolveAppDataHome({ env });
|
|
170
|
+
// The OS convention is only PREFERRED when it is already there: on a deployed
|
|
171
|
+
// box creating it would either fail (read-only namespace) or strand a
|
|
172
|
+
// publication somewhere no station instance looks.
|
|
173
|
+
if (!configured && existsSync(conventional)) candidates.push(join(conventional, "retention"));
|
|
167
174
|
if (env.APP_DATA_DIR) candidates.push(join(env.APP_DATA_DIR, "retention"));
|
|
168
175
|
candidates.push(join(conventional, "retention"));
|
|
169
176
|
|
|
@@ -9,6 +9,7 @@ import { tmpdir } from 'node:os';
|
|
|
9
9
|
import path from 'node:path';
|
|
10
10
|
import type { Argon2idDeriver } from 'cwip/guard';
|
|
11
11
|
import { setArgon2idDeriver } from 'cwip/guard';
|
|
12
|
+
import { resolveAppDataHome } from '../paths/appDataHome';
|
|
12
13
|
import {
|
|
13
14
|
createLocalDevServices,
|
|
14
15
|
createLocalGuardServices,
|
|
@@ -29,16 +30,34 @@ afterEach(() => {
|
|
|
29
30
|
});
|
|
30
31
|
|
|
31
32
|
describe('resolveAppDataRoot', () => {
|
|
32
|
-
it('hangs off the ONE app-
|
|
33
|
-
const root = resolveAppDataRoot({ appId: 'demo', env: {
|
|
33
|
+
it('hangs off the ONE configured app-data home, never a bespoke ~/.<app>', () => {
|
|
34
|
+
const root = resolveAppDataRoot({ appId: 'demo', env: { APP_DATA_HOME: '/srv/managed' } });
|
|
34
35
|
expect(root).toBe(path.join('/srv/managed', 'instances', 'demo'));
|
|
35
36
|
});
|
|
36
37
|
|
|
37
38
|
it('lets an explicit override win outright', () => {
|
|
38
|
-
expect(resolveAppDataRoot({ appId: 'demo', override: '/data/demo', env: {
|
|
39
|
+
expect(resolveAppDataRoot({ appId: 'demo', override: '/data/demo', env: { APP_DATA_HOME: '/srv' } })).toBe(
|
|
39
40
|
'/data/demo',
|
|
40
41
|
);
|
|
41
42
|
});
|
|
43
|
+
|
|
44
|
+
/*
|
|
45
|
+
* 🔴 With nothing configured it lands on the OS's convention, NOT on a folder
|
|
46
|
+
* this library invented in somebody's home. That was the published defect
|
|
47
|
+
* (2026-09-13): `cursedbelt@1.0.0` resolved the previous generation's private
|
|
48
|
+
* state root for every installer of the package.
|
|
49
|
+
*/
|
|
50
|
+
it("falls back to the OS convention, not to anybody's private folder", () => {
|
|
51
|
+
const root = resolveAppDataRoot({ appId: 'demo', env: { HOME: '/home/nobody' } });
|
|
52
|
+
expect(root).toBe(path.join(resolveAppDataHome({ env: { HOME: '/home/nobody' } }), 'instances', 'demo'));
|
|
53
|
+
expect(root).not.toContain('app-managed');
|
|
54
|
+
expect(root.startsWith('/home/nobody/')).toBe(true);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('ignores the previous generation env var entirely', () => {
|
|
58
|
+
const env = { HOME: '/home/nobody', APP_MANAGED_HOME: '/nowhere/inherited' };
|
|
59
|
+
expect(resolveAppDataRoot({ appId: 'demo', env })).not.toContain('/nowhere/inherited');
|
|
60
|
+
});
|
|
42
61
|
});
|
|
43
62
|
|
|
44
63
|
describe('loadOrMintKeyFile', () => {
|
|
@@ -12,8 +12,10 @@
|
|
|
12
12
|
* So this is the local host, once, as a tested unit. It owns four things a
|
|
13
13
|
* machine-level host owns and a library must not:
|
|
14
14
|
*
|
|
15
|
-
* 1. **Where the app's data lives** —
|
|
16
|
-
*
|
|
15
|
+
* 1. **Where the app's data lives** — `<app-data-home>/instances/<appId>`, where
|
|
16
|
+
* the home is CONFIGURATION ({@link resolveAppDataHome}): an explicit
|
|
17
|
+
* argument, else `$APP_DATA_HOME`, else the OS convention. Never a bespoke
|
|
18
|
+
* `~/.<app>` directory, and never a folder named after one machine's owner.
|
|
17
19
|
* 2. **Key custody.** The object-store URL signing key and the telemetry row
|
|
18
20
|
* integrity key are minted once, persisted `0600`, and read back **as bytes**
|
|
19
21
|
* — never as a string (V6 `key-material-as-string`; a hex string of a key
|
|
@@ -34,7 +36,6 @@
|
|
|
34
36
|
import { Database } from 'bun:sqlite';
|
|
35
37
|
import { generateKeyPairSync } from 'node:crypto';
|
|
36
38
|
import { chmodSync, existsSync, mkdirSync, readFileSync, readdirSync, statSync, type Stats, writeFileSync } from 'node:fs';
|
|
37
|
-
import { homedir } from 'node:os';
|
|
38
39
|
import path from 'node:path';
|
|
39
40
|
import {
|
|
40
41
|
assertArgon2idReady,
|
|
@@ -59,10 +60,10 @@ import type { DevServiceDeps, GuardServiceDeps } from './recipe';
|
|
|
59
60
|
import {
|
|
60
61
|
createTelemetryWriter,
|
|
61
62
|
openTelemetryDatabase,
|
|
62
|
-
resolveAppManagedHome,
|
|
63
63
|
type TelemetryDatabase,
|
|
64
64
|
type TelemetryWriter,
|
|
65
65
|
} from 'cwip/telemetry';
|
|
66
|
+
import { resolveAppDataHome } from '../paths/appDataHome';
|
|
66
67
|
|
|
67
68
|
/** Bytes in a minted key file. Matches cwip's `CC_KEY_BYTES`. */
|
|
68
69
|
export const HOST_KEY_BYTES = 32;
|
|
@@ -71,21 +72,23 @@ export interface ResolveAppDataRootOptions {
|
|
|
71
72
|
readonly appId: string;
|
|
72
73
|
/** Explicit override (a `--data-root` flag, `CC_DATA_ROOT`). Wins outright. */
|
|
73
74
|
readonly override?: string;
|
|
74
|
-
/** Environment to read `
|
|
75
|
+
/** Environment to read `APP_DATA_HOME` from. Injected by tests. */
|
|
75
76
|
readonly env?: Record<string, string | undefined>;
|
|
76
77
|
}
|
|
77
78
|
|
|
78
79
|
/**
|
|
79
|
-
* `<app-
|
|
80
|
+
* `<app-data-home>/instances/<appId>` — the app's data root.
|
|
80
81
|
*
|
|
81
82
|
* A HOST function, not a library one: `openDomainHandles` still refuses to derive
|
|
82
|
-
* a path, and this is the thing that hands it one.
|
|
83
|
+
* a path, and this is the thing that hands it one. The home underneath it is
|
|
84
|
+
* {@link resolveAppDataHome} — configuration, then the OS convention, and nothing
|
|
85
|
+
* else. A published package may not go looking for a directory it invented in
|
|
86
|
+
* somebody's home.
|
|
83
87
|
*/
|
|
84
88
|
export function resolveAppDataRoot(options: ResolveAppDataRootOptions): string {
|
|
85
89
|
const override = options.override?.trim();
|
|
86
90
|
if (override) return path.resolve(override);
|
|
87
|
-
|
|
88
|
-
return path.join(home || path.join(homedir(), '.app-managed'), 'instances', options.appId);
|
|
91
|
+
return path.join(resolveAppDataHome({ env: options.env }), 'instances', options.appId);
|
|
89
92
|
}
|
|
90
93
|
|
|
91
94
|
/**
|
|
@@ -98,6 +98,7 @@ const shipAll = async (...list: readonly Node[]): Promise<void> => {
|
|
|
98
98
|
}
|
|
99
99
|
};
|
|
100
100
|
|
|
101
|
+
// SKIPPED unless CC_PG_URL names a throwaway Postgres — this suite's subject IS the engine. `bun run test:pg` supplies one.
|
|
101
102
|
describe.skipIf(!URL_)('the shared meter against a real Postgres (04 item 4e)', () => {
|
|
102
103
|
// 120s rather than Bun's 5s, for the reason `pooledControlStores.pg.test.ts`
|
|
103
104
|
// records: this hook issues real DDL against a real engine, and on a shared CI
|
|
@@ -249,10 +249,10 @@ export function resolveManagedDomains(
|
|
|
249
249
|
|
|
250
250
|
export interface OpenDomainHandlesOptions {
|
|
251
251
|
/**
|
|
252
|
-
* Where the per-domain SQLite files live (host-resolved, e.g.
|
|
253
|
-
*
|
|
254
|
-
* is supplied via `handles` — the
|
|
255
|
-
* (handle-injection law).
|
|
252
|
+
* Where the per-domain SQLite files live (host-resolved, e.g. an
|
|
253
|
+
* `instances/<appId>/` directory under the host's own app-data root).
|
|
254
|
+
* Required unless every needed domain is supplied via `handles` — the
|
|
255
|
+
* library never invents a path from env (handle-injection law).
|
|
256
256
|
*/
|
|
257
257
|
readonly root?: string;
|
|
258
258
|
/**
|
|
@@ -61,6 +61,7 @@ const meterCount = async (): Promise<number> =>
|
|
|
61
61
|
const auditCount = async (): Promise<number> =>
|
|
62
62
|
Number(((await sql.unsafe(`SELECT COUNT(*)::int AS n FROM ${AUDIT_TRAIL_TABLE}`)) as Array<{ n: number }>)[0]?.n ?? -1);
|
|
63
63
|
|
|
64
|
+
// SKIPPED unless CC_PG_URL names a throwaway Postgres — this suite's subject IS the engine. `bun run test:pg` supplies one.
|
|
64
65
|
describe.skipIf(!URL_)('the retention job against a real Postgres (01 §4)', () => {
|
|
65
66
|
// 120s rather than Bun's 5s, for the reason the sibling pg suites record: this
|
|
66
67
|
// hook issues real DDL, and on a shared runner a timeout surfaces as a
|
|
@@ -78,6 +78,7 @@ const doc = (id: string, title: string, body: string, tenantId = TENANT) => ({
|
|
|
78
78
|
body,
|
|
79
79
|
});
|
|
80
80
|
|
|
81
|
+
// SKIPPED unless CC_PG_URL names a throwaway Postgres — this suite's subject IS the engine. `bun run test:pg` supplies one.
|
|
81
82
|
describe.skipIf(!ADMIN_URL)('createPgSearchProvider against a real Postgres (04 §3)', () => {
|
|
82
83
|
// 120s for the same reason the control-plane suite gives: this hook drops and
|
|
83
84
|
// rebuilds a whole role, database and schema, and on a shared CI runner a 5s
|
|
@@ -13,10 +13,14 @@ import { fsHlsMasterKey, fsMp4Key, fsPosterKey } from './types';
|
|
|
13
13
|
// into its own store. Skips cleanly when the checkout or ffmpeg is absent.
|
|
14
14
|
// Mirrors transcode.integration.spec.ts's harness.
|
|
15
15
|
|
|
16
|
-
const BS_DIR = process.env.BINARY_SERVER_DIR ?? '
|
|
17
|
-
const BS_PRESENT = existsSync(path.join(BS_DIR, 'src', 'index.ts'));
|
|
16
|
+
const BS_DIR = process.env.BINARY_SERVER_DIR ?? '';
|
|
17
|
+
const BS_PRESENT = BS_DIR !== '' && existsSync(path.join(BS_DIR, 'src', 'index.ts'));
|
|
18
18
|
const FFMPEG_PRESENT = Bun.which('ffmpeg') !== null;
|
|
19
19
|
|
|
20
|
+
// SKIPPED until a real binary-server checkout is present: point BINARY_SERVER_DIR at one.
|
|
21
|
+
// There is deliberately no default — a published package must not go looking in one machine's
|
|
22
|
+
// directory layout — and `binary-server` has not been re-homed here, so this skips on every host today.
|
|
23
|
+
// ffmpeg must be on PATH too: the proof is that the REMOTE side runs real ffmpeg, not that the client posted a job.
|
|
20
24
|
describe.skipIf(!BS_PRESENT || !FFMPEG_PRESENT)(
|
|
21
25
|
'binaryServerProcessing → real binary-server (integration)',
|
|
22
26
|
() => {
|
|
@@ -22,8 +22,8 @@ import type { MediaCtx } from './types';
|
|
|
22
22
|
// chunk DIRECT to bs → bs assembles on the last chunk → complete registers the catalogue row over
|
|
23
23
|
// the assembled bytes — and read the bytes back through the store. Skips cleanly when the local
|
|
24
24
|
// binary-server checkout isn't present (CI / other machines).
|
|
25
|
-
const BS_DIR = process.env.BINARY_SERVER_DIR ?? '
|
|
26
|
-
const BS_PRESENT = existsSync(path.join(BS_DIR, 'src', 'index.ts'));
|
|
25
|
+
const BS_DIR = process.env.BINARY_SERVER_DIR ?? '';
|
|
26
|
+
const BS_PRESENT = BS_DIR !== '' && existsSync(path.join(BS_DIR, 'src', 'index.ts'));
|
|
27
27
|
const ISSUER = 'https://demo.local';
|
|
28
28
|
const APP_ID = 'demo';
|
|
29
29
|
const CTX: MediaCtx = { userId: 'user-stub', tenantId: 'user-stub' };
|
|
@@ -38,6 +38,9 @@ const pem = (der: ArrayBuffer, label: string) =>
|
|
|
38
38
|
.match(/.{1,64}/g) ?? []
|
|
39
39
|
).join('\n')}\n-----END ${label}-----\n`;
|
|
40
40
|
|
|
41
|
+
// SKIPPED until a real binary-server checkout is present: point BINARY_SERVER_DIR at one.
|
|
42
|
+
// There is deliberately no default — a published package must not go looking in one machine's
|
|
43
|
+
// directory layout — and `binary-server` has not been re-homed here, so this skips on every host today.
|
|
41
44
|
describe.skipIf(!BS_PRESENT)('chunked upload → real binary-server (integration)', () => {
|
|
42
45
|
let server: TestServer | null = null;
|
|
43
46
|
let tmp = '';
|
|
@@ -26,8 +26,8 @@ import type { MediaCtx } from './types';
|
|
|
26
26
|
// generated app uses in production — and pins the load-bearing property: the app origin sees
|
|
27
27
|
// ONLY the small init/complete JSON calls, while every chunk PUTs DIRECT to binary-server.
|
|
28
28
|
// Skips cleanly when the local binary-server checkout isn't present (CI / other machines).
|
|
29
|
-
const BS_DIR = process.env.BINARY_SERVER_DIR ?? '
|
|
30
|
-
const BS_PRESENT = existsSync(path.join(BS_DIR, 'src', 'index.ts'));
|
|
29
|
+
const BS_DIR = process.env.BINARY_SERVER_DIR ?? '';
|
|
30
|
+
const BS_PRESENT = BS_DIR !== '' && existsSync(path.join(BS_DIR, 'src', 'index.ts'));
|
|
31
31
|
const ISSUER = 'https://demo.local';
|
|
32
32
|
const APP_ID = 'demo';
|
|
33
33
|
const CTX: MediaCtx = { userId: 'user-stub', tenantId: 'user-stub' };
|
|
@@ -42,6 +42,9 @@ const pem = (der: ArrayBuffer, label: string) =>
|
|
|
42
42
|
.match(/.{1,64}/g) ?? []
|
|
43
43
|
).join('\n')}\n-----END ${label}-----\n`;
|
|
44
44
|
|
|
45
|
+
// SKIPPED until a real binary-server checkout is present: point BINARY_SERVER_DIR at one.
|
|
46
|
+
// There is deliberately no default — a published package must not go looking in one machine's
|
|
47
|
+
// directory layout — and `binary-server` has not been re-homed here, so this skips on every host today.
|
|
45
48
|
describe.skipIf(!BS_PRESENT)('fileUploadClient chunked path → real binary-server (integration)', () => {
|
|
46
49
|
let server: TestServer | null = null;
|
|
47
50
|
let tmp = '';
|
|
@@ -75,6 +75,7 @@ async function heicBytes(): Promise<Uint8Array | null> {
|
|
|
75
75
|
return bytes;
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
+
// SKIPPED on a host without ffmpeg/ffprobe — it synthesizes and decodes real media. Runs by default wherever ffmpeg is installed.
|
|
78
79
|
describe.skipIf(!haveFfmpeg)('photo display derivative (HEIC)', () => {
|
|
79
80
|
let db: Database;
|
|
80
81
|
let root: string;
|
|
@@ -44,6 +44,7 @@ async function makeHeic(dest: string): Promise<boolean> {
|
|
|
44
44
|
return proc.exitCode === 0;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
// SKIPPED on a host without ffmpeg/ffprobe — it synthesizes and decodes real media. Runs by default wherever ffmpeg is installed.
|
|
47
48
|
describe.skipIf(!haveFfmpeg)('ffmpegImageThumbnail', () => {
|
|
48
49
|
test('decodes an HEVC/HEIC-style still into a width-capped JPEG', async () => {
|
|
49
50
|
const root = await mkdtemp(path.join(tmpdir(), 'cb-imgthumb-'));
|
|
@@ -13,9 +13,12 @@ import { pickFreePort, startTestServer, type TestServer } from 'cwip/testing';
|
|
|
13
13
|
// Contract: POST /api/transcode → { jobId }, GET /api/transcode/:jobId → { status, progress?, result? }.
|
|
14
14
|
// Auth: x-internal-secret header must match process.env.INTERNAL_SECRET.
|
|
15
15
|
|
|
16
|
-
const BS_DIR = process.env.BINARY_SERVER_DIR ?? '
|
|
17
|
-
const BS_PRESENT = existsSync(path.join(BS_DIR, 'src', 'index.ts'));
|
|
16
|
+
const BS_DIR = process.env.BINARY_SERVER_DIR ?? '';
|
|
17
|
+
const BS_PRESENT = BS_DIR !== '' && existsSync(path.join(BS_DIR, 'src', 'index.ts'));
|
|
18
18
|
|
|
19
|
+
// SKIPPED until a real binary-server checkout is present: point BINARY_SERVER_DIR at one.
|
|
20
|
+
// There is deliberately no default — a published package must not go looking in one machine's
|
|
21
|
+
// directory layout — and `binary-server` has not been re-homed here, so this skips on every host today.
|
|
19
22
|
describe.skipIf(!BS_PRESENT)('transcode API → real binary-server (integration)', () => {
|
|
20
23
|
let port: number;
|
|
21
24
|
let storeDir: string;
|
|
@@ -33,6 +33,7 @@ async function makeSource(dest: string, duration = 2): Promise<void> {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
// posterOnly is the memory-constrained-host path: a poster + duration, but NO heavy HLS/re-encode.
|
|
36
|
+
// SKIPPED on a host without ffmpeg/ffprobe — it synthesizes and decodes real media. Runs by default wherever ffmpeg is installed.
|
|
36
37
|
describe.skipIf(!haveFfmpeg)('processVideo posterOnly', () => {
|
|
37
38
|
test('extracts a poster + duration, ready, no HLS', async () => {
|
|
38
39
|
const root = await mkdtemp(path.join(tmpdir(), 'cb-poster-only-'));
|
package/src/shared/errors.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*
|
|
12
12
|
* Clients parse exactly this shape, so there is no per-route error drift — and no
|
|
13
13
|
* drift between a cwip-based server (which already emits it via `cwip/server`'s
|
|
14
|
-
* `errorHandler`) and a
|
|
14
|
+
* `errorHandler`) and a cursedshell one. The extra fields are additive:
|
|
15
15
|
* a client that only reads `message`/`code`/`context` keeps working unchanged.
|
|
16
16
|
*
|
|
17
17
|
* `ApiError` is the ergonomic throwable: `throw new ApiError(404, 'not found')`.
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 🔴 NO COMMENT, NO SKIP — and the doc that answers "what were they for" must stay true.
|
|
3
|
+
*
|
|
4
|
+
* ## What this cost, 2026-09-13
|
|
5
|
+
*
|
|
6
|
+
* `bun run verify` reported **5,132 pass / 82 skip / 0 fail**. Nobody could say what the 82
|
|
7
|
+
* were. Each had been written because something mattered and each had stopped running for a
|
|
8
|
+
* reason that was, by then, invisible: the gate condition was in the code
|
|
9
|
+
* (`describe.skipIf(!URL_)`), but *why that variable is unset on every host we own* was in
|
|
10
|
+
* nobody's head. A suite that carries a number like that quietly is a suite whose green means
|
|
11
|
+
* less than it says.
|
|
12
|
+
*
|
|
13
|
+
* Answering it took 16m 5s of agent time — the figure the runner's ledger recorded for the task,
|
|
14
|
+
* not an estimate — spent booting a throwaway Postgres, locating a binary-server checkout, and
|
|
15
|
+
* running each gated suite by hand to learn whether it still passes. All 82 turned out to be
|
|
16
|
+
* healthy, environment-gated proofs. That is the good outcome, and it is exactly why the next
|
|
17
|
+
* person must not have to re-derive it: the cost was never the fixing, it was the *finding
|
|
18
|
+
* out*.
|
|
19
|
+
*
|
|
20
|
+
* ## So this is a check, not a paragraph
|
|
21
|
+
*
|
|
22
|
+
* Two assertions, both of which fail the moment the record stops matching the code:
|
|
23
|
+
*
|
|
24
|
+
* 1. **Every skip site in `src` carries its reason in the comment directly above it.** A new
|
|
25
|
+
* `describe.skipIf` with no comment is a red gate, at the moment it is written, by the
|
|
26
|
+
* person who knows the answer — which is the only moment the answer is cheap.
|
|
27
|
+
* 2. **`docs/skipped-tests.md` names exactly the files that have one.** A skip that is
|
|
28
|
+
* deleted or added without updating the record reds too, so the doc cannot rot into the
|
|
29
|
+
* confident-but-wrong state that makes a doc worse than nothing.
|
|
30
|
+
*
|
|
31
|
+
* It deliberately does NOT assert a skip COUNT. The counts move with the host — ffmpeg
|
|
32
|
+
* installed or not, `CC_PG_URL` set or not — and a check that reds because someone installed
|
|
33
|
+
* `sharp` teaches people to delete the check.
|
|
34
|
+
*/
|
|
35
|
+
import { describe, expect, test } from 'bun:test';
|
|
36
|
+
import { readdirSync, readFileSync } from 'node:fs';
|
|
37
|
+
import path from 'node:path';
|
|
38
|
+
import { fileURLToPath } from 'node:url';
|
|
39
|
+
|
|
40
|
+
const SRC = fileURLToPath(new URL('.', import.meta.url));
|
|
41
|
+
const REPO = path.resolve(SRC, '..');
|
|
42
|
+
const SELF = 'src/skippedTestsAreAnswered.spec.ts';
|
|
43
|
+
const DOC = 'docs/skipped-tests.md';
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* A skip site: `describe.skip`, `.todo`, `.failing`, `.skipIf`, `.todoIf` on any of bun's three
|
|
47
|
+
* entry points, plus the jasmine-era `xit(` / `xdescribe(`.
|
|
48
|
+
*
|
|
49
|
+
* Anchored on the entry point so that ordinary identifiers containing "skip" — `skipDirs`,
|
|
50
|
+
* `skipToken`, `skipKdfReadinessGate`, all of which live in this package — are not sites.
|
|
51
|
+
*/
|
|
52
|
+
const SKIP_SITE = /\b(?:describe|it|test)\s*\.\s*(?:skip|todo|failing|skipIf|todoIf)\b|\bx(?:it|describe)\s*\(/;
|
|
53
|
+
|
|
54
|
+
/** A comment line, in either style, as it appears immediately above a skip site. */
|
|
55
|
+
const COMMENT_LINE = /^\s*(?:\/\/|\/\*|\*)/;
|
|
56
|
+
|
|
57
|
+
export interface SkipSite {
|
|
58
|
+
/** 1-indexed, so a failure message is clickable. */
|
|
59
|
+
readonly line: number;
|
|
60
|
+
readonly text: string;
|
|
61
|
+
/** The contiguous comment block directly above, with no blank line between it and the site. */
|
|
62
|
+
readonly reason: string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Every skip site in one file's source, each carrying whatever comment sits directly above it.
|
|
67
|
+
*
|
|
68
|
+
* "Directly above" is strict on purpose: a blank line between the comment and the site ends the
|
|
69
|
+
* block. The failure this guards against is a skip drifting away from the explanation that was
|
|
70
|
+
* once next to it, and a blank line is exactly how that drift starts.
|
|
71
|
+
*/
|
|
72
|
+
export const findSkipSites = (source: string): SkipSite[] => {
|
|
73
|
+
const lines = source.split('\n');
|
|
74
|
+
const sites: SkipSite[] = [];
|
|
75
|
+
for (let i = 0; i < lines.length; i += 1) {
|
|
76
|
+
const text = lines[i] as string;
|
|
77
|
+
if (!SKIP_SITE.test(text)) continue;
|
|
78
|
+
const above: string[] = [];
|
|
79
|
+
for (let j = i - 1; j >= 0; j -= 1) {
|
|
80
|
+
const prev = lines[j] as string;
|
|
81
|
+
if (!COMMENT_LINE.test(prev)) break;
|
|
82
|
+
above.unshift(prev);
|
|
83
|
+
}
|
|
84
|
+
sites.push({ line: i + 1, text: text.trim(), reason: above.join('\n') });
|
|
85
|
+
}
|
|
86
|
+
return sites;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
/** A reason has to be ABOUT the skip. Any comment at all would pass otherwise. */
|
|
90
|
+
export const isAnswered = (site: SkipSite): boolean => /skip/i.test(site.reason);
|
|
91
|
+
|
|
92
|
+
/** Every `src` file that contains at least one skip site, repo-relative and sorted. */
|
|
93
|
+
const scanSrc = (): Map<string, SkipSite[]> => {
|
|
94
|
+
const found = new Map<string, SkipSite[]>();
|
|
95
|
+
for (const entry of readdirSync(SRC, { recursive: true })) {
|
|
96
|
+
const name = String(entry);
|
|
97
|
+
if (!/\.tsx?$/.test(name)) continue;
|
|
98
|
+
const rel = `src/${name.split(path.sep).join('/')}`;
|
|
99
|
+
if (rel === SELF) continue; // the checker names the patterns it bans, so it cannot scan itself
|
|
100
|
+
const sites = findSkipSites(readFileSync(path.join(SRC, name), 'utf8'));
|
|
101
|
+
if (sites.length > 0) found.set(rel, sites);
|
|
102
|
+
}
|
|
103
|
+
return new Map([...found].sort(([a], [b]) => a.localeCompare(b)));
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* The suites `docs/skipped-tests.md` claims to cover.
|
|
108
|
+
*
|
|
109
|
+
* Only backticked paths in a TABLE ROW count, so the prose above and below the table stays free
|
|
110
|
+
* to mention any file it likes — including this one.
|
|
111
|
+
*/
|
|
112
|
+
const documentedSuites = async (): Promise<Set<string>> => {
|
|
113
|
+
const doc = await Bun.file(path.join(REPO, DOC)).text();
|
|
114
|
+
const rows = doc.split('\n').filter((l) => l.trimStart().startsWith('|'));
|
|
115
|
+
const named = new Set<string>();
|
|
116
|
+
for (const row of rows) for (const m of row.matchAll(/`(src\/[^`]+\.tsx?)`/g)) named.add(m[1] as string);
|
|
117
|
+
return named;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
describe('every skip in src answers for itself', () => {
|
|
121
|
+
test('each skip site carries its reason in the comment directly above it', () => {
|
|
122
|
+
const unanswered: string[] = [];
|
|
123
|
+
for (const [file, sites] of scanSrc())
|
|
124
|
+
for (const site of sites) if (!isAnswered(site)) unanswered.push(`${file}:${site.line} ${site.text}`);
|
|
125
|
+
|
|
126
|
+
expect(
|
|
127
|
+
unanswered,
|
|
128
|
+
`A skipped test with no stated reason is a question nobody can answer later — answering the 82 already here\n` +
|
|
129
|
+
`cost a task of its own on 2026-09-13 (16m 5s, per the runner's ledger). Put one line directly above the\n` +
|
|
130
|
+
`skip saying what it is WAITING FOR (a service, a fixture, a\n` +
|
|
131
|
+
`browser, a decision), mentioning the word "skip", and add a row to ${DOC}. If it passes today, unskip it\n` +
|
|
132
|
+
`instead. Never delete a test to make the number fall.\n\nUnanswered:\n ${unanswered.join('\n ')}`,
|
|
133
|
+
).toEqual([]);
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
describe(`${DOC} matches the suite`, () => {
|
|
138
|
+
test('it names every file that carries a skip', async () => {
|
|
139
|
+
const documented = await documentedSuites();
|
|
140
|
+
const missing = [...scanSrc().keys()].filter((f) => !documented.has(f));
|
|
141
|
+
expect(
|
|
142
|
+
missing,
|
|
143
|
+
`These files gained a skip that ${DOC} does not mention. Add a table row: what it waits for, how to run it,\n` +
|
|
144
|
+
`and when it was last seen green.\n\n ${missing.join('\n ')}`,
|
|
145
|
+
).toEqual([]);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
test('it names no file that has stopped carrying one', async () => {
|
|
149
|
+
const live = scanSrc();
|
|
150
|
+
const stale = [...(await documentedSuites())].filter((f) => !live.has(f));
|
|
151
|
+
expect(
|
|
152
|
+
stale,
|
|
153
|
+
`${DOC} still lists these as skipped, but they no longer contain a skip site. Good news — delete the rows\n` +
|
|
154
|
+
`(and move the count) so the record stops claiming something that is no longer true.\n\n ${stale.join('\n ')}`,
|
|
155
|
+
).toEqual([]);
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* The detector's own failure path. A gate nobody has seen RED is a gate nobody knows works, and
|
|
161
|
+
* this one's whole value is that it fires on the day a skip is introduced.
|
|
162
|
+
*/
|
|
163
|
+
describe('the detector itself', () => {
|
|
164
|
+
test('an uncommented skip is a finding', () => {
|
|
165
|
+
const sites = findSkipSites(["describe.skipIf(!URL_)('x', () => {", '});'].join('\n'));
|
|
166
|
+
expect(sites).toHaveLength(1);
|
|
167
|
+
expect(isAnswered(sites[0] as SkipSite)).toBe(false);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
test('a skip whose comment explains the skip is not', () => {
|
|
171
|
+
const sites = findSkipSites(
|
|
172
|
+
['// SKIPPED unless CC_PG_URL names a real Postgres.', "describe.skipIf(!URL_)('x', () => {", '});'].join('\n'),
|
|
173
|
+
);
|
|
174
|
+
expect(isAnswered(sites[0] as SkipSite)).toBe(true);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
test('a comment about something else does NOT answer for the skip', () => {
|
|
178
|
+
const sites = findSkipSites(
|
|
179
|
+
['// posterOnly is the memory-constrained-host path.', "describe.skipIf(!ffmpeg)('x', () => {", '});'].join('\n'),
|
|
180
|
+
);
|
|
181
|
+
expect(isAnswered(sites[0] as SkipSite)).toBe(false);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
test('a blank line between the comment and the skip breaks the block', () => {
|
|
185
|
+
const sites = findSkipSites(
|
|
186
|
+
['// SKIPPED unless CC_PG_URL is set.', '', "describe.skipIf(!URL_)('x', () => {", '});'].join('\n'),
|
|
187
|
+
);
|
|
188
|
+
expect(sites[0]?.reason).toBe('');
|
|
189
|
+
expect(isAnswered(sites[0] as SkipSite)).toBe(false);
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
test('a JSDoc block above the skip counts as the reason', () => {
|
|
193
|
+
const sites = findSkipSites(
|
|
194
|
+
['/**', ' * SKIPPED until the browser harness exists.', ' */', "it.skip('x', () => {});"].join('\n'),
|
|
195
|
+
);
|
|
196
|
+
expect(isAnswered(sites[0] as SkipSite)).toBe(true);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
test('it finds the other spellings too', () => {
|
|
200
|
+
expect(findSkipSites("it.todo('later');")).toHaveLength(1);
|
|
201
|
+
expect(findSkipSites("test.failing('known bad');")).toHaveLength(1);
|
|
202
|
+
expect(findSkipSites("xit('old style', () => {});")).toHaveLength(1);
|
|
203
|
+
expect(findSkipSites("xdescribe('old style', () => {});")).toHaveLength(1);
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
test('an identifier that merely contains "skip" is not a skip site', () => {
|
|
207
|
+
expect(findSkipSites('const skip = new Set(opts.skipDirs ?? []);')).toEqual([]);
|
|
208
|
+
expect(findSkipSites('if (options.skipKdfReadinessGate !== true) assertArgon2idReady();')).toEqual([]);
|
|
209
|
+
expect(findSkipSites('const q = useQuery({ queryKey: k, initialPageParam: skipToken });')).toEqual([]);
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
test('this package has skip sites to find — a detector that finds nothing proves nothing', () => {
|
|
213
|
+
expect(scanSrc().size).toBeGreaterThan(0);
|
|
214
|
+
});
|
|
215
|
+
});
|