@pyric/ui 0.1.0-alpha.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +79 -0
- package/dist/agents/ContextWindowUsage.d.ts +67 -0
- package/dist/agents/ContextWindowUsage.d.ts.map +1 -0
- package/dist/agents/ContextWindowUsage.js +115 -0
- package/dist/agents/ContextWindowUsage.js.map +1 -0
- package/dist/agents/EmptyState.d.ts +18 -0
- package/dist/agents/EmptyState.d.ts.map +1 -0
- package/dist/agents/EmptyState.js +11 -0
- package/dist/agents/EmptyState.js.map +1 -0
- package/dist/agents/Fold.d.ts +37 -0
- package/dist/agents/Fold.d.ts.map +1 -0
- package/dist/agents/Fold.js +18 -0
- package/dist/agents/Fold.js.map +1 -0
- package/dist/agents/Modal.d.ts +25 -0
- package/dist/agents/Modal.d.ts.map +1 -0
- package/dist/agents/Modal.js +28 -0
- package/dist/agents/Modal.js.map +1 -0
- package/dist/agents/PulsingDot.d.ts +21 -0
- package/dist/agents/PulsingDot.d.ts.map +1 -0
- package/dist/agents/PulsingDot.js +18 -0
- package/dist/agents/PulsingDot.js.map +1 -0
- package/dist/agents/index.d.ts +15 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +15 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/auth/authApi.d.ts +32 -0
- package/dist/auth/authApi.d.ts.map +1 -0
- package/dist/auth/authApi.js +27 -0
- package/dist/auth/authApi.js.map +1 -0
- package/dist/auth/claims.d.ts +27 -0
- package/dist/auth/claims.d.ts.map +1 -0
- package/dist/auth/claims.js +58 -0
- package/dist/auth/claims.js.map +1 -0
- package/dist/auth/components/AuthProviderToggles.d.ts +31 -0
- package/dist/auth/components/AuthProviderToggles.d.ts.map +1 -0
- package/dist/auth/components/AuthProviderToggles.js +48 -0
- package/dist/auth/components/AuthProviderToggles.js.map +1 -0
- package/dist/auth/components/AuthSignInHelper.d.ts +57 -0
- package/dist/auth/components/AuthSignInHelper.d.ts.map +1 -0
- package/dist/auth/components/AuthSignInHelper.js +69 -0
- package/dist/auth/components/AuthSignInHelper.js.map +1 -0
- package/dist/auth/components/AuthUserForm.d.ts +84 -0
- package/dist/auth/components/AuthUserForm.d.ts.map +1 -0
- package/dist/auth/components/AuthUserForm.js +89 -0
- package/dist/auth/components/AuthUserForm.js.map +1 -0
- package/dist/auth/components/AuthUserList.d.ts +51 -0
- package/dist/auth/components/AuthUserList.d.ts.map +1 -0
- package/dist/auth/components/AuthUserList.js +46 -0
- package/dist/auth/components/AuthUserList.js.map +1 -0
- package/dist/auth/components/ClaimsField.d.ts +22 -0
- package/dist/auth/components/ClaimsField.d.ts.map +1 -0
- package/dist/auth/components/ClaimsField.js +11 -0
- package/dist/auth/components/ClaimsField.js.map +1 -0
- package/dist/auth/components/confirmActions.d.ts +40 -0
- package/dist/auth/components/confirmActions.d.ts.map +1 -0
- package/dist/auth/components/confirmActions.js +49 -0
- package/dist/auth/components/confirmActions.js.map +1 -0
- package/dist/auth/controller.d.ts +73 -0
- package/dist/auth/controller.d.ts.map +1 -0
- package/dist/auth/controller.js +139 -0
- package/dist/auth/controller.js.map +1 -0
- package/dist/auth/hooks/index.d.ts +7 -0
- package/dist/auth/hooks/index.d.ts.map +1 -0
- package/dist/auth/hooks/index.js +7 -0
- package/dist/auth/hooks/index.js.map +1 -0
- package/dist/auth/hooks/useAuthFlowHelper.d.ts +30 -0
- package/dist/auth/hooks/useAuthFlowHelper.d.ts.map +1 -0
- package/dist/auth/hooks/useAuthFlowHelper.js +30 -0
- package/dist/auth/hooks/useAuthFlowHelper.js.map +1 -0
- package/dist/auth/hooks/useAuthProviderConfig.d.ts +37 -0
- package/dist/auth/hooks/useAuthProviderConfig.d.ts.map +1 -0
- package/dist/auth/hooks/useAuthProviderConfig.js +98 -0
- package/dist/auth/hooks/useAuthProviderConfig.js.map +1 -0
- package/dist/auth/hooks/useAuthUserEditor.d.ts +30 -0
- package/dist/auth/hooks/useAuthUserEditor.d.ts.map +1 -0
- package/dist/auth/hooks/useAuthUserEditor.js +27 -0
- package/dist/auth/hooks/useAuthUserEditor.js.map +1 -0
- package/dist/auth/hooks/useAuthUsers.d.ts +38 -0
- package/dist/auth/hooks/useAuthUsers.d.ts.map +1 -0
- package/dist/auth/hooks/useAuthUsers.js +111 -0
- package/dist/auth/hooks/useAuthUsers.js.map +1 -0
- package/dist/auth/index.d.ts +11 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +13 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/providers.d.ts +11 -0
- package/dist/auth/providers.d.ts.map +1 -0
- package/dist/auth/providers.js +28 -0
- package/dist/auth/providers.js.map +1 -0
- package/dist/auth/reducers/userEditor.d.ts +55 -0
- package/dist/auth/reducers/userEditor.d.ts.map +1 -0
- package/dist/auth/reducers/userEditor.js +136 -0
- package/dist/auth/reducers/userEditor.js.map +1 -0
- package/dist/events/components/ActivityActionItems.d.ts +45 -0
- package/dist/events/components/ActivityActionItems.d.ts.map +1 -0
- package/dist/events/components/ActivityActionItems.js +68 -0
- package/dist/events/components/ActivityActionItems.js.map +1 -0
- package/dist/events/components/ActivityGrid.d.ts +65 -0
- package/dist/events/components/ActivityGrid.d.ts.map +1 -0
- package/dist/events/components/ActivityGrid.js +61 -0
- package/dist/events/components/ActivityGrid.js.map +1 -0
- package/dist/events/components/ActivityGridRow.d.ts +31 -0
- package/dist/events/components/ActivityGridRow.d.ts.map +1 -0
- package/dist/events/components/ActivityGridRow.js +23 -0
- package/dist/events/components/ActivityGridRow.js.map +1 -0
- package/dist/events/components/ProposedChangeDiff.d.ts +46 -0
- package/dist/events/components/ProposedChangeDiff.d.ts.map +1 -0
- package/dist/events/components/ProposedChangeDiff.js +60 -0
- package/dist/events/components/ProposedChangeDiff.js.map +1 -0
- package/dist/events/components/format.d.ts +11 -0
- package/dist/events/components/format.d.ts.map +1 -0
- package/dist/events/components/format.js +26 -0
- package/dist/events/components/format.js.map +1 -0
- package/dist/events/components/index.d.ts +6 -0
- package/dist/events/components/index.d.ts.map +1 -0
- package/dist/events/components/index.js +6 -0
- package/dist/events/components/index.js.map +1 -0
- package/dist/events/digest.d.ts +167 -0
- package/dist/events/digest.d.ts.map +1 -0
- package/dist/events/digest.js +426 -0
- package/dist/events/digest.js.map +1 -0
- package/dist/events/hooks/index.d.ts +3 -0
- package/dist/events/hooks/index.d.ts.map +1 -0
- package/dist/events/hooks/index.js +3 -0
- package/dist/events/hooks/index.js.map +1 -0
- package/dist/events/hooks/useActivityDigest.d.ts +27 -0
- package/dist/events/hooks/useActivityDigest.d.ts.map +1 -0
- package/dist/events/hooks/useActivityDigest.js +18 -0
- package/dist/events/hooks/useActivityDigest.js.map +1 -0
- package/dist/events/hooks/useActivityStream.d.ts +44 -0
- package/dist/events/hooks/useActivityStream.d.ts.map +1 -0
- package/dist/events/hooks/useActivityStream.js +38 -0
- package/dist/events/hooks/useActivityStream.js.map +1 -0
- package/dist/events/index.d.ts +15 -0
- package/dist/events/index.d.ts.map +1 -0
- package/dist/events/index.js +14 -0
- package/dist/events/index.js.map +1 -0
- package/dist/events/types.d.ts +160 -0
- package/dist/events/types.d.ts.map +1 -0
- package/dist/events/types.js +21 -0
- package/dist/events/types.js.map +1 -0
- package/dist/firestore/components/CollectionList.d.ts +22 -0
- package/dist/firestore/components/CollectionList.d.ts.map +1 -0
- package/dist/firestore/components/CollectionList.js +21 -0
- package/dist/firestore/components/CollectionList.js.map +1 -0
- package/dist/firestore/components/DeleteWithConfirm.d.ts +38 -0
- package/dist/firestore/components/DeleteWithConfirm.d.ts.map +1 -0
- package/dist/firestore/components/DeleteWithConfirm.js +33 -0
- package/dist/firestore/components/DeleteWithConfirm.js.map +1 -0
- package/dist/firestore/components/DocumentEditor.d.ts +47 -0
- package/dist/firestore/components/DocumentEditor.d.ts.map +1 -0
- package/dist/firestore/components/DocumentEditor.js +176 -0
- package/dist/firestore/components/DocumentEditor.js.map +1 -0
- package/dist/firestore/components/DocumentList.d.ts +60 -0
- package/dist/firestore/components/DocumentList.d.ts.map +1 -0
- package/dist/firestore/components/DocumentList.js +39 -0
- package/dist/firestore/components/DocumentList.js.map +1 -0
- package/dist/firestore/components/DocumentPreview.d.ts +68 -0
- package/dist/firestore/components/DocumentPreview.d.ts.map +1 -0
- package/dist/firestore/components/DocumentPreview.js +76 -0
- package/dist/firestore/components/DocumentPreview.js.map +1 -0
- package/dist/firestore/components/FieldRenderer.d.ts +17 -0
- package/dist/firestore/components/FieldRenderer.d.ts.map +1 -0
- package/dist/firestore/components/FieldRenderer.js +16 -0
- package/dist/firestore/components/FieldRenderer.js.map +1 -0
- package/dist/firestore/components/QueryBuilder.d.ts +25 -0
- package/dist/firestore/components/QueryBuilder.d.ts.map +1 -0
- package/dist/firestore/components/QueryBuilder.js +78 -0
- package/dist/firestore/components/QueryBuilder.js.map +1 -0
- package/dist/firestore/components/ReferencePicker.d.ts +33 -0
- package/dist/firestore/components/ReferencePicker.d.ts.map +1 -0
- package/dist/firestore/components/ReferencePicker.js +42 -0
- package/dist/firestore/components/ReferencePicker.js.map +1 -0
- package/dist/firestore/components/TreeEntry.d.ts +15 -0
- package/dist/firestore/components/TreeEntry.d.ts.map +1 -0
- package/dist/firestore/components/TreeEntry.js +23 -0
- package/dist/firestore/components/TreeEntry.js.map +1 -0
- package/dist/firestore/components/context.d.ts +18 -0
- package/dist/firestore/components/context.d.ts.map +1 -0
- package/dist/firestore/components/context.js +7 -0
- package/dist/firestore/components/context.js.map +1 -0
- package/dist/firestore/fieldEditors/array.d.ts +3 -0
- package/dist/firestore/fieldEditors/array.d.ts.map +1 -0
- package/dist/firestore/fieldEditors/array.js +16 -0
- package/dist/firestore/fieldEditors/array.js.map +1 -0
- package/dist/firestore/fieldEditors/boolean.d.ts +3 -0
- package/dist/firestore/fieldEditors/boolean.d.ts.map +1 -0
- package/dist/firestore/fieldEditors/boolean.js +13 -0
- package/dist/firestore/fieldEditors/boolean.js.map +1 -0
- package/dist/firestore/fieldEditors/bytes.d.ts +4 -0
- package/dist/firestore/fieldEditors/bytes.d.ts.map +1 -0
- package/dist/firestore/fieldEditors/bytes.js +31 -0
- package/dist/firestore/fieldEditors/bytes.js.map +1 -0
- package/dist/firestore/fieldEditors/geopoint.d.ts +4 -0
- package/dist/firestore/fieldEditors/geopoint.d.ts.map +1 -0
- package/dist/firestore/fieldEditors/geopoint.js +32 -0
- package/dist/firestore/fieldEditors/geopoint.js.map +1 -0
- package/dist/firestore/fieldEditors/map.d.ts +3 -0
- package/dist/firestore/fieldEditors/map.d.ts.map +1 -0
- package/dist/firestore/fieldEditors/map.js +19 -0
- package/dist/firestore/fieldEditors/map.js.map +1 -0
- package/dist/firestore/fieldEditors/null.d.ts +3 -0
- package/dist/firestore/fieldEditors/null.d.ts.map +1 -0
- package/dist/firestore/fieldEditors/null.js +17 -0
- package/dist/firestore/fieldEditors/null.js.map +1 -0
- package/dist/firestore/fieldEditors/number.d.ts +3 -0
- package/dist/firestore/fieldEditors/number.d.ts.map +1 -0
- package/dist/firestore/fieldEditors/number.js +24 -0
- package/dist/firestore/fieldEditors/number.js.map +1 -0
- package/dist/firestore/fieldEditors/reference.d.ts +4 -0
- package/dist/firestore/fieldEditors/reference.d.ts.map +1 -0
- package/dist/firestore/fieldEditors/reference.js +49 -0
- package/dist/firestore/fieldEditors/reference.js.map +1 -0
- package/dist/firestore/fieldEditors/registry.d.ts +16 -0
- package/dist/firestore/fieldEditors/registry.d.ts.map +1 -0
- package/dist/firestore/fieldEditors/registry.js +42 -0
- package/dist/firestore/fieldEditors/registry.js.map +1 -0
- package/dist/firestore/fieldEditors/string.d.ts +3 -0
- package/dist/firestore/fieldEditors/string.d.ts.map +1 -0
- package/dist/firestore/fieldEditors/string.js +13 -0
- package/dist/firestore/fieldEditors/string.js.map +1 -0
- package/dist/firestore/fieldEditors/timestamp.d.ts +4 -0
- package/dist/firestore/fieldEditors/timestamp.d.ts.map +1 -0
- package/dist/firestore/fieldEditors/timestamp.js +52 -0
- package/dist/firestore/fieldEditors/timestamp.js.map +1 -0
- package/dist/firestore/fieldEditors/types.d.ts +64 -0
- package/dist/firestore/fieldEditors/types.d.ts.map +1 -0
- package/dist/firestore/fieldEditors/types.js +2 -0
- package/dist/firestore/fieldEditors/types.js.map +1 -0
- package/dist/firestore/fieldEditors/vector.d.ts +29 -0
- package/dist/firestore/fieldEditors/vector.d.ts.map +1 -0
- package/dist/firestore/fieldEditors/vector.js +93 -0
- package/dist/firestore/fieldEditors/vector.js.map +1 -0
- package/dist/firestore/firestoreApi.d.ts +35 -0
- package/dist/firestore/firestoreApi.d.ts.map +1 -0
- package/dist/firestore/firestoreApi.js +28 -0
- package/dist/firestore/firestoreApi.js.map +1 -0
- package/dist/firestore/hooks/coerceError.d.ts +17 -0
- package/dist/firestore/hooks/coerceError.d.ts.map +1 -0
- package/dist/firestore/hooks/coerceError.js +41 -0
- package/dist/firestore/hooks/coerceError.js.map +1 -0
- package/dist/firestore/hooks/index.d.ts +10 -0
- package/dist/firestore/hooks/index.d.ts.map +1 -0
- package/dist/firestore/hooks/index.js +10 -0
- package/dist/firestore/hooks/index.js.map +1 -0
- package/dist/firestore/hooks/useCollectionList.d.ts +37 -0
- package/dist/firestore/hooks/useCollectionList.d.ts.map +1 -0
- package/dist/firestore/hooks/useCollectionList.js +51 -0
- package/dist/firestore/hooks/useCollectionList.js.map +1 -0
- package/dist/firestore/hooks/useDocumentEditor.d.ts +58 -0
- package/dist/firestore/hooks/useDocumentEditor.d.ts.map +1 -0
- package/dist/firestore/hooks/useDocumentEditor.js +68 -0
- package/dist/firestore/hooks/useDocumentEditor.js.map +1 -0
- package/dist/firestore/hooks/useDocumentList.d.ts +45 -0
- package/dist/firestore/hooks/useDocumentList.d.ts.map +1 -0
- package/dist/firestore/hooks/useDocumentList.js +112 -0
- package/dist/firestore/hooks/useDocumentList.js.map +1 -0
- package/dist/firestore/hooks/useDocumentSubcollections.d.ts +29 -0
- package/dist/firestore/hooks/useDocumentSubcollections.d.ts.map +1 -0
- package/dist/firestore/hooks/useDocumentSubcollections.js +48 -0
- package/dist/firestore/hooks/useDocumentSubcollections.js.map +1 -0
- package/dist/firestore/hooks/useFirestoreCollection.d.ts +14 -0
- package/dist/firestore/hooks/useFirestoreCollection.d.ts.map +1 -0
- package/dist/firestore/hooks/useFirestoreCollection.js +35 -0
- package/dist/firestore/hooks/useFirestoreCollection.js.map +1 -0
- package/dist/firestore/hooks/useFirestoreDoc.d.ts +17 -0
- package/dist/firestore/hooks/useFirestoreDoc.d.ts.map +1 -0
- package/dist/firestore/hooks/useFirestoreDoc.js +34 -0
- package/dist/firestore/hooks/useFirestoreDoc.js.map +1 -0
- package/dist/firestore/hooks/useQueryBuilder.d.ts +51 -0
- package/dist/firestore/hooks/useQueryBuilder.d.ts.map +1 -0
- package/dist/firestore/hooks/useQueryBuilder.js +110 -0
- package/dist/firestore/hooks/useQueryBuilder.js.map +1 -0
- package/dist/firestore/hooks/useRecursiveDelete.d.ts +40 -0
- package/dist/firestore/hooks/useRecursiveDelete.d.ts.map +1 -0
- package/dist/firestore/hooks/useRecursiveDelete.js +44 -0
- package/dist/firestore/hooks/useRecursiveDelete.js.map +1 -0
- package/dist/firestore/hooks/useReferencePicker.d.ts +70 -0
- package/dist/firestore/hooks/useReferencePicker.d.ts.map +1 -0
- package/dist/firestore/hooks/useReferencePicker.js +140 -0
- package/dist/firestore/hooks/useReferencePicker.js.map +1 -0
- package/dist/firestore/import/parseImport.d.ts +55 -0
- package/dist/firestore/import/parseImport.d.ts.map +1 -0
- package/dist/firestore/import/parseImport.js +101 -0
- package/dist/firestore/import/parseImport.js.map +1 -0
- package/dist/firestore/index.d.ts +20 -0
- package/dist/firestore/index.d.ts.map +1 -0
- package/dist/firestore/index.js +28 -0
- package/dist/firestore/index.js.map +1 -0
- package/dist/firestore/reducers/defaults.d.ts +10 -0
- package/dist/firestore/reducers/defaults.d.ts.map +1 -0
- package/dist/firestore/reducers/defaults.js +37 -0
- package/dist/firestore/reducers/defaults.js.map +1 -0
- package/dist/firestore/reducers/documentEditor.d.ts +23 -0
- package/dist/firestore/reducers/documentEditor.d.ts.map +1 -0
- package/dist/firestore/reducers/documentEditor.js +199 -0
- package/dist/firestore/reducers/documentEditor.js.map +1 -0
- package/dist/firestore/reducers/tree.d.ts +28 -0
- package/dist/firestore/reducers/tree.d.ts.map +1 -0
- package/dist/firestore/reducers/tree.js +129 -0
- package/dist/firestore/reducers/tree.js.map +1 -0
- package/dist/firestore/reducers/types.d.ts +112 -0
- package/dist/firestore/reducers/types.d.ts.map +1 -0
- package/dist/firestore/reducers/types.js +2 -0
- package/dist/firestore/reducers/types.js.map +1 -0
- package/dist/firestore/reducers/validation.d.ts +25 -0
- package/dist/firestore/reducers/validation.d.ts.map +1 -0
- package/dist/firestore/reducers/validation.js +121 -0
- package/dist/firestore/reducers/validation.js.map +1 -0
- package/dist/firestore/types.d.ts +77 -0
- package/dist/firestore/types.d.ts.map +1 -0
- package/dist/firestore/types.js +196 -0
- package/dist/firestore/types.js.map +1 -0
- package/dist/firestore/validation/ids.d.ts +23 -0
- package/dist/firestore/validation/ids.d.ts.map +1 -0
- package/dist/firestore/validation/ids.js +46 -0
- package/dist/firestore/validation/ids.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/primitives/Badge.d.ts +28 -0
- package/dist/primitives/Badge.d.ts.map +1 -0
- package/dist/primitives/Badge.js +11 -0
- package/dist/primitives/Badge.js.map +1 -0
- package/dist/primitives/ConfirmDialog.d.ts +42 -0
- package/dist/primitives/ConfirmDialog.d.ts.map +1 -0
- package/dist/primitives/ConfirmDialog.js +61 -0
- package/dist/primitives/ConfirmDialog.js.map +1 -0
- package/dist/primitives/CopyButton.d.ts +28 -0
- package/dist/primitives/CopyButton.d.ts.map +1 -0
- package/dist/primitives/CopyButton.js +27 -0
- package/dist/primitives/CopyButton.js.map +1 -0
- package/dist/primitives/JsonView.d.ts +29 -0
- package/dist/primitives/JsonView.d.ts.map +1 -0
- package/dist/primitives/JsonView.js +56 -0
- package/dist/primitives/JsonView.js.map +1 -0
- package/dist/primitives/SegmentedControl.d.ts +37 -0
- package/dist/primitives/SegmentedControl.d.ts.map +1 -0
- package/dist/primitives/SegmentedControl.js +18 -0
- package/dist/primitives/SegmentedControl.js.map +1 -0
- package/dist/primitives/Toast.d.ts +48 -0
- package/dist/primitives/Toast.d.ts.map +1 -0
- package/dist/primitives/Toast.js +60 -0
- package/dist/primitives/Toast.js.map +1 -0
- package/dist/primitives/VirtualList.d.ts +37 -0
- package/dist/primitives/VirtualList.d.ts.map +1 -0
- package/dist/primitives/VirtualList.js +47 -0
- package/dist/primitives/VirtualList.js.map +1 -0
- package/dist/primitives/hooks/useContainerSize.d.ts +29 -0
- package/dist/primitives/hooks/useContainerSize.d.ts.map +1 -0
- package/dist/primitives/hooks/useContainerSize.js +45 -0
- package/dist/primitives/hooks/useContainerSize.js.map +1 -0
- package/dist/primitives/index.d.ts +10 -0
- package/dist/primitives/index.d.ts.map +1 -0
- package/dist/primitives/index.js +10 -0
- package/dist/primitives/index.js.map +1 -0
- package/dist/primitives/useConfirm.d.ts +34 -0
- package/dist/primitives/useConfirm.d.ts.map +1 -0
- package/dist/primitives/useConfirm.js +63 -0
- package/dist/primitives/useConfirm.js.map +1 -0
- package/dist/rtdb/components/RtdbPathBar.d.ts +31 -0
- package/dist/rtdb/components/RtdbPathBar.d.ts.map +1 -0
- package/dist/rtdb/components/RtdbPathBar.js +47 -0
- package/dist/rtdb/components/RtdbPathBar.js.map +1 -0
- package/dist/rtdb/components/RtdbTree.d.ts +38 -0
- package/dist/rtdb/components/RtdbTree.d.ts.map +1 -0
- package/dist/rtdb/components/RtdbTree.js +103 -0
- package/dist/rtdb/components/RtdbTree.js.map +1 -0
- package/dist/rtdb/editor.d.ts +25 -0
- package/dist/rtdb/editor.d.ts.map +1 -0
- package/dist/rtdb/editor.js +79 -0
- package/dist/rtdb/editor.js.map +1 -0
- package/dist/rtdb/hooks/useRtdbTree.d.ts +31 -0
- package/dist/rtdb/hooks/useRtdbTree.d.ts.map +1 -0
- package/dist/rtdb/hooks/useRtdbTree.js +49 -0
- package/dist/rtdb/hooks/useRtdbTree.js.map +1 -0
- package/dist/rtdb/index.d.ts +17 -0
- package/dist/rtdb/index.d.ts.map +1 -0
- package/dist/rtdb/index.js +21 -0
- package/dist/rtdb/index.js.map +1 -0
- package/dist/rtdb/pathInput.d.ts +28 -0
- package/dist/rtdb/pathInput.d.ts.map +1 -0
- package/dist/rtdb/pathInput.js +40 -0
- package/dist/rtdb/pathInput.js.map +1 -0
- package/dist/rtdb/reducers/tree.d.ts +86 -0
- package/dist/rtdb/reducers/tree.d.ts.map +1 -0
- package/dist/rtdb/reducers/tree.js +131 -0
- package/dist/rtdb/reducers/tree.js.map +1 -0
- package/dist/rtdb/rtdbApi.d.ts +20 -0
- package/dist/rtdb/rtdbApi.d.ts.map +1 -0
- package/dist/rtdb/rtdbApi.js +2 -0
- package/dist/rtdb/rtdbApi.js.map +1 -0
- package/dist/rtdb/values.d.ts +44 -0
- package/dist/rtdb/values.d.ts.map +1 -0
- package/dist/rtdb/values.js +143 -0
- package/dist/rtdb/values.js.map +1 -0
- package/dist/rules/components/DenialInspector.d.ts +18 -0
- package/dist/rules/components/DenialInspector.d.ts.map +1 -0
- package/dist/rules/components/DenialInspector.js +58 -0
- package/dist/rules/components/DenialInspector.js.map +1 -0
- package/dist/rules/components/format.d.ts +56 -0
- package/dist/rules/components/format.d.ts.map +1 -0
- package/dist/rules/components/format.js +137 -0
- package/dist/rules/components/format.js.map +1 -0
- package/dist/rules/components/index.d.ts +4 -0
- package/dist/rules/components/index.d.ts.map +1 -0
- package/dist/rules/components/index.js +4 -0
- package/dist/rules/components/index.js.map +1 -0
- package/dist/rules/components/scope.d.ts +10 -0
- package/dist/rules/components/scope.d.ts.map +1 -0
- package/dist/rules/components/scope.js +72 -0
- package/dist/rules/components/scope.js.map +1 -0
- package/dist/rules/hooks/index.d.ts +2 -0
- package/dist/rules/hooks/index.d.ts.map +1 -0
- package/dist/rules/hooks/index.js +2 -0
- package/dist/rules/hooks/index.js.map +1 -0
- package/dist/rules/hooks/useDenialTrace.d.ts +51 -0
- package/dist/rules/hooks/useDenialTrace.d.ts.map +1 -0
- package/dist/rules/hooks/useDenialTrace.js +58 -0
- package/dist/rules/hooks/useDenialTrace.js.map +1 -0
- package/dist/rules/index.d.ts +14 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/index.js +13 -0
- package/dist/rules/index.js.map +1 -0
- package/dist/rules/types.d.ts +75 -0
- package/dist/rules/types.d.ts.map +1 -0
- package/dist/rules/types.js +2 -0
- package/dist/rules/types.js.map +1 -0
- package/dist/storage/collisionRename.d.ts +73 -0
- package/dist/storage/collisionRename.d.ts.map +1 -0
- package/dist/storage/collisionRename.js +113 -0
- package/dist/storage/collisionRename.js.map +1 -0
- package/dist/storage/components/DeleteSelectionWithConfirm.d.ts +68 -0
- package/dist/storage/components/DeleteSelectionWithConfirm.d.ts.map +1 -0
- package/dist/storage/components/DeleteSelectionWithConfirm.js +82 -0
- package/dist/storage/components/DeleteSelectionWithConfirm.js.map +1 -0
- package/dist/storage/components/ObjectBrowser.d.ts +75 -0
- package/dist/storage/components/ObjectBrowser.d.ts.map +1 -0
- package/dist/storage/components/ObjectBrowser.js +59 -0
- package/dist/storage/components/ObjectBrowser.js.map +1 -0
- package/dist/storage/components/ObjectInspector.d.ts +43 -0
- package/dist/storage/components/ObjectInspector.d.ts.map +1 -0
- package/dist/storage/components/ObjectInspector.js +92 -0
- package/dist/storage/components/ObjectInspector.js.map +1 -0
- package/dist/storage/components/PathBreadcrumb.d.ts +30 -0
- package/dist/storage/components/PathBreadcrumb.d.ts.map +1 -0
- package/dist/storage/components/PathBreadcrumb.js +26 -0
- package/dist/storage/components/PathBreadcrumb.js.map +1 -0
- package/dist/storage/components/UploadDropzone.d.ts +50 -0
- package/dist/storage/components/UploadDropzone.d.ts.map +1 -0
- package/dist/storage/components/UploadDropzone.js +109 -0
- package/dist/storage/components/UploadDropzone.js.map +1 -0
- package/dist/storage/folderPlaceholder.d.ts +14 -0
- package/dist/storage/folderPlaceholder.d.ts.map +1 -0
- package/dist/storage/folderPlaceholder.js +27 -0
- package/dist/storage/folderPlaceholder.js.map +1 -0
- package/dist/storage/hooks/index.d.ts +9 -0
- package/dist/storage/hooks/index.d.ts.map +1 -0
- package/dist/storage/hooks/index.js +9 -0
- package/dist/storage/hooks/index.js.map +1 -0
- package/dist/storage/hooks/useMetadataEditor.d.ts +114 -0
- package/dist/storage/hooks/useMetadataEditor.d.ts.map +1 -0
- package/dist/storage/hooks/useMetadataEditor.js +193 -0
- package/dist/storage/hooks/useMetadataEditor.js.map +1 -0
- package/dist/storage/hooks/useObjectUpload.d.ts +109 -0
- package/dist/storage/hooks/useObjectUpload.d.ts.map +1 -0
- package/dist/storage/hooks/useObjectUpload.js +134 -0
- package/dist/storage/hooks/useObjectUpload.js.map +1 -0
- package/dist/storage/hooks/usePathState.d.ts +43 -0
- package/dist/storage/hooks/usePathState.d.ts.map +1 -0
- package/dist/storage/hooks/usePathState.js +42 -0
- package/dist/storage/hooks/usePathState.js.map +1 -0
- package/dist/storage/hooks/useStorageDelete.d.ts +73 -0
- package/dist/storage/hooks/useStorageDelete.d.ts.map +1 -0
- package/dist/storage/hooks/useStorageDelete.js +114 -0
- package/dist/storage/hooks/useStorageDelete.js.map +1 -0
- package/dist/storage/hooks/useStorageList.d.ts +74 -0
- package/dist/storage/hooks/useStorageList.d.ts.map +1 -0
- package/dist/storage/hooks/useStorageList.js +167 -0
- package/dist/storage/hooks/useStorageList.js.map +1 -0
- package/dist/storage/hooks/useStorageObject.d.ts +34 -0
- package/dist/storage/hooks/useStorageObject.d.ts.map +1 -0
- package/dist/storage/hooks/useStorageObject.js +114 -0
- package/dist/storage/hooks/useStorageObject.js.map +1 -0
- package/dist/storage/hooks/useStorageRulesGate.d.ts +128 -0
- package/dist/storage/hooks/useStorageRulesGate.d.ts.map +1 -0
- package/dist/storage/hooks/useStorageRulesGate.js +158 -0
- package/dist/storage/hooks/useStorageRulesGate.js.map +1 -0
- package/dist/storage/hooks/useStorageSelection.d.ts +32 -0
- package/dist/storage/hooks/useStorageSelection.d.ts.map +1 -0
- package/dist/storage/hooks/useStorageSelection.js +55 -0
- package/dist/storage/hooks/useStorageSelection.js.map +1 -0
- package/dist/storage/index.d.ts +11 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +17 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/pendingPrefixes.d.ts +73 -0
- package/dist/storage/pendingPrefixes.d.ts.map +1 -0
- package/dist/storage/pendingPrefixes.js +98 -0
- package/dist/storage/pendingPrefixes.js.map +1 -0
- package/dist/storage/previews.d.ts +51 -0
- package/dist/storage/previews.d.ts.map +1 -0
- package/dist/storage/previews.js +73 -0
- package/dist/storage/previews.js.map +1 -0
- package/dist/storage/storageApi.d.ts +30 -0
- package/dist/storage/storageApi.d.ts.map +1 -0
- package/dist/storage/storageApi.js +13 -0
- package/dist/storage/storageApi.js.map +1 -0
- package/dist/traffic/components/RuleHeatmap.d.ts +34 -0
- package/dist/traffic/components/RuleHeatmap.d.ts.map +1 -0
- package/dist/traffic/components/RuleHeatmap.js +40 -0
- package/dist/traffic/components/RuleHeatmap.js.map +1 -0
- package/dist/traffic/components/TrafficDetail.d.ts +33 -0
- package/dist/traffic/components/TrafficDetail.d.ts.map +1 -0
- package/dist/traffic/components/TrafficDetail.js +28 -0
- package/dist/traffic/components/TrafficDetail.js.map +1 -0
- package/dist/traffic/components/TrafficGroupRow.d.ts +28 -0
- package/dist/traffic/components/TrafficGroupRow.d.ts.map +1 -0
- package/dist/traffic/components/TrafficGroupRow.js +18 -0
- package/dist/traffic/components/TrafficGroupRow.js.map +1 -0
- package/dist/traffic/components/TrafficLineChart.d.ts +34 -0
- package/dist/traffic/components/TrafficLineChart.d.ts.map +1 -0
- package/dist/traffic/components/TrafficLineChart.js +49 -0
- package/dist/traffic/components/TrafficLineChart.js.map +1 -0
- package/dist/traffic/components/TrafficLog.d.ts +52 -0
- package/dist/traffic/components/TrafficLog.d.ts.map +1 -0
- package/dist/traffic/components/TrafficLog.js +34 -0
- package/dist/traffic/components/TrafficLog.js.map +1 -0
- package/dist/traffic/components/TrafficMetricCards.d.ts +26 -0
- package/dist/traffic/components/TrafficMetricCards.d.ts.map +1 -0
- package/dist/traffic/components/TrafficMetricCards.js +24 -0
- package/dist/traffic/components/TrafficMetricCards.js.map +1 -0
- package/dist/traffic/components/TrafficRow.d.ts +40 -0
- package/dist/traffic/components/TrafficRow.d.ts.map +1 -0
- package/dist/traffic/components/TrafficRow.js +27 -0
- package/dist/traffic/components/TrafficRow.js.map +1 -0
- package/dist/traffic/components/TrafficStats.d.ts +18 -0
- package/dist/traffic/components/TrafficStats.d.ts.map +1 -0
- package/dist/traffic/components/TrafficStats.js +19 -0
- package/dist/traffic/components/TrafficStats.js.map +1 -0
- package/dist/traffic/components/TrafficTimeline.d.ts +81 -0
- package/dist/traffic/components/TrafficTimeline.d.ts.map +1 -0
- package/dist/traffic/components/TrafficTimeline.js +72 -0
- package/dist/traffic/components/TrafficTimeline.js.map +1 -0
- package/dist/traffic/components/format.d.ts +13 -0
- package/dist/traffic/components/format.d.ts.map +1 -0
- package/dist/traffic/components/format.js +24 -0
- package/dist/traffic/components/format.js.map +1 -0
- package/dist/traffic/components/index.d.ts +11 -0
- package/dist/traffic/components/index.d.ts.map +1 -0
- package/dist/traffic/components/index.js +11 -0
- package/dist/traffic/components/index.js.map +1 -0
- package/dist/traffic/hooks/index.d.ts +8 -0
- package/dist/traffic/hooks/index.d.ts.map +1 -0
- package/dist/traffic/hooks/index.js +8 -0
- package/dist/traffic/hooks/index.js.map +1 -0
- package/dist/traffic/hooks/useRuleHeatmap.d.ts +33 -0
- package/dist/traffic/hooks/useRuleHeatmap.d.ts.map +1 -0
- package/dist/traffic/hooks/useRuleHeatmap.js +54 -0
- package/dist/traffic/hooks/useRuleHeatmap.js.map +1 -0
- package/dist/traffic/hooks/useTrafficBuckets.d.ts +71 -0
- package/dist/traffic/hooks/useTrafficBuckets.d.ts.map +1 -0
- package/dist/traffic/hooks/useTrafficBuckets.js +74 -0
- package/dist/traffic/hooks/useTrafficBuckets.js.map +1 -0
- package/dist/traffic/hooks/useTrafficFilter.d.ts +40 -0
- package/dist/traffic/hooks/useTrafficFilter.d.ts.map +1 -0
- package/dist/traffic/hooks/useTrafficFilter.js +33 -0
- package/dist/traffic/hooks/useTrafficFilter.js.map +1 -0
- package/dist/traffic/hooks/useTrafficGroups.d.ts +47 -0
- package/dist/traffic/hooks/useTrafficGroups.d.ts.map +1 -0
- package/dist/traffic/hooks/useTrafficGroups.js +73 -0
- package/dist/traffic/hooks/useTrafficGroups.js.map +1 -0
- package/dist/traffic/hooks/useTrafficMetrics.d.ts +66 -0
- package/dist/traffic/hooks/useTrafficMetrics.d.ts.map +1 -0
- package/dist/traffic/hooks/useTrafficMetrics.js +156 -0
- package/dist/traffic/hooks/useTrafficMetrics.js.map +1 -0
- package/dist/traffic/hooks/useTrafficMonitor.d.ts +56 -0
- package/dist/traffic/hooks/useTrafficMonitor.d.ts.map +1 -0
- package/dist/traffic/hooks/useTrafficMonitor.js +58 -0
- package/dist/traffic/hooks/useTrafficMonitor.js.map +1 -0
- package/dist/traffic/hooks/useTrafficStats.d.ts +32 -0
- package/dist/traffic/hooks/useTrafficStats.d.ts.map +1 -0
- package/dist/traffic/hooks/useTrafficStats.js +45 -0
- package/dist/traffic/hooks/useTrafficStats.js.map +1 -0
- package/dist/traffic/index.d.ts +4 -0
- package/dist/traffic/index.d.ts.map +1 -0
- package/dist/traffic/index.js +3 -0
- package/dist/traffic/index.js.map +1 -0
- package/dist/traffic/types.d.ts +72 -0
- package/dist/traffic/types.d.ts.map +1 -0
- package/dist/traffic/types.js +10 -0
- package/dist/traffic/types.js.map +1 -0
- package/package.json +116 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { type FirebaseStorage, type StorageAuth, type StorageRules } from 'pyric/storage';
|
|
2
|
+
export type StorageRulesGateStatus = 'idle' | 'loading' | 'ready' | 'error';
|
|
3
|
+
/**
|
|
4
|
+
* Where the active ruleset came from:
|
|
5
|
+
* - `'option'` — the explicit `rules` option (string or pre-parsed).
|
|
6
|
+
* - `'sandbox'` — the ruleset deployed on the sandbox handle
|
|
7
|
+
* (`getStorageSandbox(ctx, { rules })`), read off the handle's
|
|
8
|
+
* `StorageService`.
|
|
9
|
+
* - `'none'` — no rules reachable. Every verdict allows
|
|
10
|
+
* (open-by-default, the same semantics `pyric/storage`'s
|
|
11
|
+
* enforcement layer applies when no rules are configured).
|
|
12
|
+
*/
|
|
13
|
+
export type StorageRulesSource = 'option' | 'sandbox' | 'none';
|
|
14
|
+
/**
|
|
15
|
+
* Per-path verdict. `pyric/storage`'s rules subset has exactly two
|
|
16
|
+
* verbs (`read` | `write` — the granular get/list/create/update/
|
|
17
|
+
* delete forms are a parser follow-up), so `delete` and `upload` are
|
|
18
|
+
* DERIVED aliases of `write`: Firebase Storage's `write` permission
|
|
19
|
+
* governs create, overwrite, AND delete.
|
|
20
|
+
*/
|
|
21
|
+
export interface StorageGateVerdict {
|
|
22
|
+
read: boolean;
|
|
23
|
+
write: boolean;
|
|
24
|
+
/** Derived — always `=== write` under the two-verb subset. */
|
|
25
|
+
delete: boolean;
|
|
26
|
+
/** Derived — always `=== write` under the two-verb subset. */
|
|
27
|
+
upload: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Evaluator reason traces for DENIED verbs (`"no rule matches…"` /
|
|
30
|
+
* `"match /… : condition false"`); empty arrays when allowed.
|
|
31
|
+
* Feed into disabled-state tooltips and `data-*-reason` attributes.
|
|
32
|
+
*/
|
|
33
|
+
reasons: {
|
|
34
|
+
read: string[];
|
|
35
|
+
write: string[];
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export interface UseStorageRulesGateOptions {
|
|
39
|
+
/**
|
|
40
|
+
* Path (or paths) to pre-evaluate into `verdicts`, keyed by the
|
|
41
|
+
* normalized path. Ad-hoc paths (e.g. browser rows) go through
|
|
42
|
+
* `verdictFor` instead — the two are the same evaluation.
|
|
43
|
+
*/
|
|
44
|
+
paths?: string | readonly string[];
|
|
45
|
+
/**
|
|
46
|
+
* Explicit rules source — raw rules text (parsed here; a malformed
|
|
47
|
+
* string surfaces as `status: 'error'`) or a pre-parsed
|
|
48
|
+
* `StorageRules` handle. Overrides the sandbox's deployed ruleset
|
|
49
|
+
* when both exist. REQUIRED for meaningful verdicts on prod
|
|
50
|
+
* handles: production rules live server-side and are not readable
|
|
51
|
+
* through the client SDK, so the gate cannot discover them.
|
|
52
|
+
*/
|
|
53
|
+
rules?: string | StorageRules;
|
|
54
|
+
/**
|
|
55
|
+
* Identity override. `null` is anonymous; OMIT the field to use
|
|
56
|
+
* the handle's own identity (the sandbox context's `auth`). Prod
|
|
57
|
+
* handles carry no client-readable identity claims here, so prod
|
|
58
|
+
* callers pass the signed-in user's `{ uid, token }` explicitly.
|
|
59
|
+
*/
|
|
60
|
+
identity?: StorageAuth | null;
|
|
61
|
+
/**
|
|
62
|
+
* The about-to-write payload bound to `request.resource` for the
|
|
63
|
+
* WRITE evaluation — pass `{ size, contentType }` when gating a
|
|
64
|
+
* specific upload so size/contentType-conditioned rules evaluate
|
|
65
|
+
* truthfully. When omitted, `request.resource` is unset, which is
|
|
66
|
+
* exactly DELETE semantics (deletes carry no inbound payload) —
|
|
67
|
+
* a rule like `request.resource.size < N` then denies, the
|
|
68
|
+
* conservative answer for uploads.
|
|
69
|
+
*/
|
|
70
|
+
writeResource?: {
|
|
71
|
+
size: number;
|
|
72
|
+
contentType?: string;
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
export interface UseStorageRulesGateResult {
|
|
76
|
+
/** `'idle'` only when `storage` is null/undefined. */
|
|
77
|
+
status: StorageRulesGateStatus;
|
|
78
|
+
/** Where the active ruleset came from. */
|
|
79
|
+
source: StorageRulesSource;
|
|
80
|
+
/**
|
|
81
|
+
* True for prod handles: client-side evaluation is ADVISORY there
|
|
82
|
+
* — the server's evaluator is authoritative, and this gate only
|
|
83
|
+
* sees whatever the `rules` option mirrors (which can drift from
|
|
84
|
+
* what is deployed). Sandbox verdicts come from the same evaluator
|
|
85
|
+
* the sandbox enforces with, so they are truthful.
|
|
86
|
+
*/
|
|
87
|
+
advisory: boolean;
|
|
88
|
+
/** The identity the verdicts evaluate under. */
|
|
89
|
+
identity: StorageAuth | null;
|
|
90
|
+
/** Pre-evaluated verdicts for `options.paths`, keyed by normalized path. */
|
|
91
|
+
verdicts: Record<string, StorageGateVerdict>;
|
|
92
|
+
/**
|
|
93
|
+
* Evaluate an arbitrary path under the current ruleset + identity.
|
|
94
|
+
* Pure and synchronous once `status` is `'ready'`; before that
|
|
95
|
+
* (and whenever no rules are reachable) it returns the allow-all
|
|
96
|
+
* verdict — the gate FAILS OPEN, because affordances are advisory
|
|
97
|
+
* and the real enforcement (sandbox throw / server denial) stays
|
|
98
|
+
* authoritative.
|
|
99
|
+
*/
|
|
100
|
+
verdictFor: (path: string) => StorageGateVerdict;
|
|
101
|
+
/** Rules-resolution failure (e.g. a malformed `rules` string). */
|
|
102
|
+
error: Error | undefined;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Pre-flight rules evaluation — the M7 differentiator. Evaluates the
|
|
106
|
+
* current identity against paths BEFORE the click, so components can
|
|
107
|
+
* annotate denied affordances (`data-pyric-denied`, disabled-with-
|
|
108
|
+
* reason) instead of letting the user discover a denial via a thrown
|
|
109
|
+
* `storage/unauthorized`.
|
|
110
|
+
*
|
|
111
|
+
* Rules discovery: a sandbox handle carries its deployed ruleset
|
|
112
|
+
* (`getStorageSandbox(ctx, { rules })` parses it into the handle's
|
|
113
|
+
* `StorageService`) — the hook reads it through the handle's target,
|
|
114
|
+
* so sandbox callers pass nothing. Identity likewise defaults to the
|
|
115
|
+
* handle's `SandboxContext.auth`. Prod handles expose neither
|
|
116
|
+
* (rules + claims live server-side), so prod callers pass `rules` +
|
|
117
|
+
* `identity` explicitly and treat verdicts as advisory (`advisory:
|
|
118
|
+
* true` — the server is authoritative).
|
|
119
|
+
*
|
|
120
|
+
* Evaluation contract (mirrors `pyric/storage`'s own enforcement):
|
|
121
|
+
* `resource` (the existing object) is bound as `null` — the gate
|
|
122
|
+
* pre-evaluates without fetching per-path metadata, matching how the
|
|
123
|
+
* sandbox enforces `listAll`. Rules conditioned on existing-object
|
|
124
|
+
* state (`resource.*`) evaluate as if the object doesn't exist; the
|
|
125
|
+
* common identity/path/payload-shaped rules evaluate exactly.
|
|
126
|
+
*/
|
|
127
|
+
export declare function useStorageRulesGate(storage: FirebaseStorage | null | undefined, options?: UseStorageRulesGateOptions): UseStorageRulesGateResult;
|
|
128
|
+
//# sourceMappingURL=useStorageRulesGate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useStorageRulesGate.d.ts","sourceRoot":"","sources":["../../../src/storage/hooks/useStorageRulesGate.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,eAAe,EACpB,KAAK,WAAW,EAEhB,KAAK,YAAY,EAClB,MAAM,eAAe,CAAC;AAGvB,MAAM,MAAM,sBAAsB,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AAE5E;;;;;;;;;GASG;AACH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;AAE/D;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,8DAA8D;IAC9D,MAAM,EAAE,OAAO,CAAC;IAChB,8DAA8D;IAC9D,MAAM,EAAE,OAAO,CAAC;IAChB;;;;OAIG;IACH,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CAC9C;AAED,MAAM,WAAW,0BAA0B;IACzC;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;IACnC;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,YAAY,CAAC;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAC9B;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACxD;AAED,MAAM,WAAW,yBAAyB;IACxC,sDAAsD;IACtD,MAAM,EAAE,sBAAsB,CAAC;IAC/B,0CAA0C;IAC1C,MAAM,EAAE,kBAAkB,CAAC;IAC3B;;;;;;OAMG;IACH,QAAQ,EAAE,OAAO,CAAC;IAClB,gDAAgD;IAChD,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAC;IAC7B,4EAA4E;IAC5E,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAC7C;;;;;;;OAOG;IACH,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,kBAAkB,CAAC;IACjD,kEAAkE;IAClE,KAAK,EAAE,KAAK,GAAG,SAAS,CAAC;CAC1B;AAqBD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,EAC3C,OAAO,GAAE,0BAA+B,GACvC,yBAAyB,CAiI3B"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
2
|
+
import { TARGET_SYMBOL, parseStorageRules, evaluateStorageRules, } from 'pyric/storage';
|
|
3
|
+
import { normalizeStoragePath } from './usePathState.js';
|
|
4
|
+
/** Shared allow-all verdict — idle/loading/error and rules-less states. */
|
|
5
|
+
const ALLOW_ALL = Object.freeze({
|
|
6
|
+
read: true,
|
|
7
|
+
write: true,
|
|
8
|
+
delete: true,
|
|
9
|
+
upload: true,
|
|
10
|
+
reasons: Object.freeze({
|
|
11
|
+
read: [],
|
|
12
|
+
write: [],
|
|
13
|
+
}),
|
|
14
|
+
});
|
|
15
|
+
/**
|
|
16
|
+
* Pre-flight rules evaluation — the M7 differentiator. Evaluates the
|
|
17
|
+
* current identity against paths BEFORE the click, so components can
|
|
18
|
+
* annotate denied affordances (`data-pyric-denied`, disabled-with-
|
|
19
|
+
* reason) instead of letting the user discover a denial via a thrown
|
|
20
|
+
* `storage/unauthorized`.
|
|
21
|
+
*
|
|
22
|
+
* Rules discovery: a sandbox handle carries its deployed ruleset
|
|
23
|
+
* (`getStorageSandbox(ctx, { rules })` parses it into the handle's
|
|
24
|
+
* `StorageService`) — the hook reads it through the handle's target,
|
|
25
|
+
* so sandbox callers pass nothing. Identity likewise defaults to the
|
|
26
|
+
* handle's `SandboxContext.auth`. Prod handles expose neither
|
|
27
|
+
* (rules + claims live server-side), so prod callers pass `rules` +
|
|
28
|
+
* `identity` explicitly and treat verdicts as advisory (`advisory:
|
|
29
|
+
* true` — the server is authoritative).
|
|
30
|
+
*
|
|
31
|
+
* Evaluation contract (mirrors `pyric/storage`'s own enforcement):
|
|
32
|
+
* `resource` (the existing object) is bound as `null` — the gate
|
|
33
|
+
* pre-evaluates without fetching per-path metadata, matching how the
|
|
34
|
+
* sandbox enforces `listAll`. Rules conditioned on existing-object
|
|
35
|
+
* state (`resource.*`) evaluate as if the object doesn't exist; the
|
|
36
|
+
* common identity/path/payload-shaped rules evaluate exactly.
|
|
37
|
+
*/
|
|
38
|
+
export function useStorageRulesGate(storage, options = {}) {
|
|
39
|
+
const { paths, rules: rulesOption, identity: identityOption, writeResource } = options;
|
|
40
|
+
const target = storage == null ? null : storage[TARGET_SYMBOL];
|
|
41
|
+
const [state, setState] = useState(() => ({
|
|
42
|
+
status: storage == null ? 'idle' : 'loading',
|
|
43
|
+
rules: null,
|
|
44
|
+
source: 'none',
|
|
45
|
+
error: undefined,
|
|
46
|
+
}));
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
if (target == null) {
|
|
49
|
+
setState({ status: 'idle', rules: null, source: 'none', error: undefined });
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
// Explicit option wins — and is the only channel for prod.
|
|
53
|
+
if (rulesOption != null) {
|
|
54
|
+
try {
|
|
55
|
+
const parsed = typeof rulesOption === 'string' ? parseStorageRules(rulesOption) : rulesOption;
|
|
56
|
+
setState({ status: 'ready', rules: parsed, source: 'option', error: undefined });
|
|
57
|
+
}
|
|
58
|
+
catch (e) {
|
|
59
|
+
setState({
|
|
60
|
+
status: 'error',
|
|
61
|
+
rules: null,
|
|
62
|
+
source: 'none',
|
|
63
|
+
error: e instanceof Error ? e : new Error(String(e)),
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (target.kind === 'sandbox') {
|
|
69
|
+
let cancelled = false;
|
|
70
|
+
setState({ status: 'loading', rules: null, source: 'none', error: undefined });
|
|
71
|
+
target.servicePromise
|
|
72
|
+
.then((service) => {
|
|
73
|
+
if (cancelled)
|
|
74
|
+
return;
|
|
75
|
+
setState({
|
|
76
|
+
status: 'ready',
|
|
77
|
+
rules: service.rules,
|
|
78
|
+
source: service.rules ? 'sandbox' : 'none',
|
|
79
|
+
error: undefined,
|
|
80
|
+
});
|
|
81
|
+
})
|
|
82
|
+
.catch((e) => {
|
|
83
|
+
if (cancelled)
|
|
84
|
+
return;
|
|
85
|
+
setState({
|
|
86
|
+
status: 'error',
|
|
87
|
+
rules: null,
|
|
88
|
+
source: 'none',
|
|
89
|
+
error: e instanceof Error ? e : new Error(String(e)),
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
return () => {
|
|
93
|
+
cancelled = true;
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
// Prod handle without an explicit ruleset: nothing to evaluate —
|
|
97
|
+
// open verdicts, advisory.
|
|
98
|
+
setState({ status: 'ready', rules: null, source: 'none', error: undefined });
|
|
99
|
+
}, [target, rulesOption]);
|
|
100
|
+
// `undefined` means "derive from the handle"; an explicit `null`
|
|
101
|
+
// means anonymous.
|
|
102
|
+
const identity = identityOption !== undefined
|
|
103
|
+
? identityOption
|
|
104
|
+
: target?.kind === 'sandbox'
|
|
105
|
+
? target.context.auth
|
|
106
|
+
: null;
|
|
107
|
+
const { rules, status } = state;
|
|
108
|
+
const writeSize = writeResource?.size;
|
|
109
|
+
const writeContentType = writeResource?.contentType;
|
|
110
|
+
const verdictFor = useCallback((path) => {
|
|
111
|
+
if (rules == null)
|
|
112
|
+
return ALLOW_ALL;
|
|
113
|
+
const evaluate = (method) => evaluateStorageRules(rules, {
|
|
114
|
+
request: {
|
|
115
|
+
auth: identity,
|
|
116
|
+
method,
|
|
117
|
+
path: normalizeStoragePath(path),
|
|
118
|
+
...(method === 'write' && writeSize !== undefined
|
|
119
|
+
? { resource: { size: writeSize, contentType: writeContentType } }
|
|
120
|
+
: {}),
|
|
121
|
+
},
|
|
122
|
+
resource: null,
|
|
123
|
+
});
|
|
124
|
+
const read = evaluate('read');
|
|
125
|
+
const write = evaluate('write');
|
|
126
|
+
return {
|
|
127
|
+
read: read.allowed,
|
|
128
|
+
write: write.allowed,
|
|
129
|
+
delete: write.allowed,
|
|
130
|
+
upload: write.allowed,
|
|
131
|
+
reasons: {
|
|
132
|
+
read: read.allowed ? [] : read.reasons,
|
|
133
|
+
write: write.allowed ? [] : write.reasons,
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
}, [rules, identity, writeSize, writeContentType]);
|
|
137
|
+
const pathsKey = typeof paths === 'string' ? paths : (paths ?? []).join('\n');
|
|
138
|
+
const verdicts = useMemo(() => {
|
|
139
|
+
const list = typeof paths === 'string' ? [paths] : (paths ?? []);
|
|
140
|
+
const out = {};
|
|
141
|
+
for (const p of list) {
|
|
142
|
+
out[normalizeStoragePath(p)] = verdictFor(p);
|
|
143
|
+
}
|
|
144
|
+
return out;
|
|
145
|
+
// `pathsKey` stands in for the (possibly inline) array identity,
|
|
146
|
+
// so a fresh-but-equal `paths` array doesn't churn the record.
|
|
147
|
+
}, [pathsKey, verdictFor]);
|
|
148
|
+
return {
|
|
149
|
+
status,
|
|
150
|
+
source: state.source,
|
|
151
|
+
advisory: target?.kind === 'prod',
|
|
152
|
+
identity,
|
|
153
|
+
verdicts,
|
|
154
|
+
verdictFor,
|
|
155
|
+
error: state.error,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=useStorageRulesGate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useStorageRulesGate.js","sourceRoot":"","sources":["../../../src/storage/hooks/useStorageRulesGate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAClE,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,oBAAoB,GAKrB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAuGzD,2EAA2E;AAC3E,MAAM,SAAS,GAAuB,MAAM,CAAC,MAAM,CAAC;IAClD,IAAI,EAAE,IAAI;IACV,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,IAAI;IACZ,MAAM,EAAE,IAAI;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC;QACrB,IAAI,EAAE,EAAc;QACpB,KAAK,EAAE,EAAc;KACtB,CAAkC;CACpC,CAAC,CAAC;AASH;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,mBAAmB,CACjC,OAA2C,EAC3C,UAAsC,EAAE;IAExC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,cAAc,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC;IAEvF,MAAM,MAAM,GAAG,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IAE/D,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAa,GAAG,EAAE,CAAC,CAAC;QACpD,MAAM,EAAE,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;QAC5C,KAAK,EAAE,IAAI;QACX,MAAM,EAAE,MAAM;QACd,KAAK,EAAE,SAAS;KACjB,CAAC,CAAC,CAAC;IAEJ,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;YACnB,QAAQ,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;YAC5E,OAAO;QACT,CAAC;QACD,2DAA2D;QAC3D,IAAI,WAAW,IAAI,IAAI,EAAE,CAAC;YACxB,IAAI,CAAC;gBACH,MAAM,MAAM,GACV,OAAO,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;gBACjF,QAAQ,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;YACnF,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,QAAQ,CAAC;oBACP,MAAM,EAAE,OAAO;oBACf,KAAK,EAAE,IAAI;oBACX,MAAM,EAAE,MAAM;oBACd,KAAK,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;iBACrD,CAAC,CAAC;YACL,CAAC;YACD,OAAO;QACT,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC9B,IAAI,SAAS,GAAG,KAAK,CAAC;YACtB,QAAQ,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;YAC/E,MAAM,CAAC,cAAc;iBAClB,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;gBAChB,IAAI,SAAS;oBAAE,OAAO;gBACtB,QAAQ,CAAC;oBACP,MAAM,EAAE,OAAO;oBACf,KAAK,EAAE,OAAO,CAAC,KAAK;oBACpB,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM;oBAC1C,KAAK,EAAE,SAAS;iBACjB,CAAC,CAAC;YACL,CAAC,CAAC;iBACD,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;gBACX,IAAI,SAAS;oBAAE,OAAO;gBACtB,QAAQ,CAAC;oBACP,MAAM,EAAE,OAAO;oBACf,KAAK,EAAE,IAAI;oBACX,MAAM,EAAE,MAAM;oBACd,KAAK,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;iBACrD,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YACL,OAAO,GAAG,EAAE;gBACV,SAAS,GAAG,IAAI,CAAC;YACnB,CAAC,CAAC;QACJ,CAAC;QACD,iEAAiE;QACjE,2BAA2B;QAC3B,QAAQ,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAC/E,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;IAE1B,iEAAiE;IACjE,mBAAmB;IACnB,MAAM,QAAQ,GACZ,cAAc,KAAK,SAAS;QAC1B,CAAC,CAAC,cAAc;QAChB,CAAC,CAAC,MAAM,EAAE,IAAI,KAAK,SAAS;YAC1B,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI;YACrB,CAAC,CAAC,IAAI,CAAC;IAEb,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IAChC,MAAM,SAAS,GAAG,aAAa,EAAE,IAAI,CAAC;IACtC,MAAM,gBAAgB,GAAG,aAAa,EAAE,WAAW,CAAC;IAEpD,MAAM,UAAU,GAAG,WAAW,CAC5B,CAAC,IAAY,EAAsB,EAAE;QACnC,IAAI,KAAK,IAAI,IAAI;YAAE,OAAO,SAAS,CAAC;QACpC,MAAM,QAAQ,GAAG,CAAC,MAAqB,EAAE,EAAE,CACzC,oBAAoB,CAAC,KAAK,EAAE;YAC1B,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,MAAM;gBACN,IAAI,EAAE,oBAAoB,CAAC,IAAI,CAAC;gBAChC,GAAG,CAAC,MAAM,KAAK,OAAO,IAAI,SAAS,KAAK,SAAS;oBAC/C,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE,EAAE;oBAClE,CAAC,CAAC,EAAE,CAAC;aACR;YACD,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;QACL,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC9B,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;QAChC,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,OAAO;YAClB,KAAK,EAAE,KAAK,CAAC,OAAO;YACpB,MAAM,EAAE,KAAK,CAAC,OAAO;YACrB,MAAM,EAAE,KAAK,CAAC,OAAO;YACrB,OAAO,EAAE;gBACP,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO;gBACtC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO;aAC1C;SACF,CAAC;IACJ,CAAC,EACD,CAAC,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,gBAAgB,CAAC,CAC/C,CAAC;IAEF,MAAM,QAAQ,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9E,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,EAAE;QAC5B,MAAM,IAAI,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;QACjE,MAAM,GAAG,GAAuC,EAAE,CAAC;QACnD,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACrB,GAAG,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;QAC/C,CAAC;QACD,OAAO,GAAG,CAAC;QACX,iEAAiE;QACjE,+DAA+D;IACjE,CAAC,EAAE,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC;IAE3B,OAAO;QACL,MAAM;QACN,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,QAAQ,EAAE,MAAM,EAAE,IAAI,KAAK,MAAM;QACjC,QAAQ;QACR,QAAQ;QACR,UAAU;QACV,KAAK,EAAE,KAAK,CAAC,KAAK;KACnB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the selection tracks per row — a structural subset of
|
|
3
|
+
* `StorageListEntry`, so `useStorageList`'s entries pass straight
|
|
4
|
+
* in. The `kind` decides the delete verb later (object →
|
|
5
|
+
* `deleteObject`, folder → recursive).
|
|
6
|
+
*/
|
|
7
|
+
export interface StorageSelectionEntry {
|
|
8
|
+
kind: 'folder' | 'object';
|
|
9
|
+
fullPath: string;
|
|
10
|
+
}
|
|
11
|
+
export interface UseStorageSelectionResult {
|
|
12
|
+
/** Selected entries in selection order. */
|
|
13
|
+
selected: StorageSelectionEntry[];
|
|
14
|
+
size: number;
|
|
15
|
+
isSelected: (fullPath: string) => boolean;
|
|
16
|
+
/** Add/remove — the checkbox verb. */
|
|
17
|
+
toggle: (entry: StorageSelectionEntry) => void;
|
|
18
|
+
select: (entry: StorageSelectionEntry) => void;
|
|
19
|
+
deselect: (fullPath: string) => void;
|
|
20
|
+
/** Replace the selection (e.g. a "select all" over
|
|
21
|
+
* `list.entries`). */
|
|
22
|
+
selectAll: (entries: StorageSelectionEntry[]) => void;
|
|
23
|
+
clear: () => void;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Multi-select state over storage rows, keyed by `fullPath`.
|
|
27
|
+
* Deliberately dumb: it doesn't watch the list, so clear it on path
|
|
28
|
+
* change (or after a bulk op via the delete hook's outcome) — the
|
|
29
|
+
* consumer owns that policy.
|
|
30
|
+
*/
|
|
31
|
+
export declare function useStorageSelection(): UseStorageSelectionResult;
|
|
32
|
+
//# sourceMappingURL=useStorageSelection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useStorageSelection.d.ts","sourceRoot":"","sources":["../../../src/storage/hooks/useStorageSelection.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,yBAAyB;IACxC,2CAA2C;IAC3C,QAAQ,EAAE,qBAAqB,EAAE,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IAC1C,sCAAsC;IACtC,MAAM,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAC/C,MAAM,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAC/C,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC;2BACuB;IACvB,SAAS,EAAE,CAAC,OAAO,EAAE,qBAAqB,EAAE,KAAK,IAAI,CAAC;IACtD,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,IAAI,yBAAyB,CAuD/D"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { useCallback, useMemo, useState } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Multi-select state over storage rows, keyed by `fullPath`.
|
|
4
|
+
* Deliberately dumb: it doesn't watch the list, so clear it on path
|
|
5
|
+
* change (or after a bulk op via the delete hook's outcome) — the
|
|
6
|
+
* consumer owns that policy.
|
|
7
|
+
*/
|
|
8
|
+
export function useStorageSelection() {
|
|
9
|
+
const [map, setMap] = useState(() => new Map());
|
|
10
|
+
const isSelected = useCallback((fullPath) => map.has(fullPath), [map]);
|
|
11
|
+
const select = useCallback((entry) => {
|
|
12
|
+
setMap((prev) => {
|
|
13
|
+
if (prev.has(entry.fullPath))
|
|
14
|
+
return prev;
|
|
15
|
+
const next = new Map(prev);
|
|
16
|
+
next.set(entry.fullPath, entry);
|
|
17
|
+
return next;
|
|
18
|
+
});
|
|
19
|
+
}, []);
|
|
20
|
+
const deselect = useCallback((fullPath) => {
|
|
21
|
+
setMap((prev) => {
|
|
22
|
+
if (!prev.has(fullPath))
|
|
23
|
+
return prev;
|
|
24
|
+
const next = new Map(prev);
|
|
25
|
+
next.delete(fullPath);
|
|
26
|
+
return next;
|
|
27
|
+
});
|
|
28
|
+
}, []);
|
|
29
|
+
const toggle = useCallback((entry) => {
|
|
30
|
+
setMap((prev) => {
|
|
31
|
+
const next = new Map(prev);
|
|
32
|
+
if (next.has(entry.fullPath))
|
|
33
|
+
next.delete(entry.fullPath);
|
|
34
|
+
else
|
|
35
|
+
next.set(entry.fullPath, entry);
|
|
36
|
+
return next;
|
|
37
|
+
});
|
|
38
|
+
}, []);
|
|
39
|
+
const selectAll = useCallback((entries) => {
|
|
40
|
+
setMap(new Map(entries.map((e) => [e.fullPath, e])));
|
|
41
|
+
}, []);
|
|
42
|
+
const clear = useCallback(() => setMap(new Map()), []);
|
|
43
|
+
const selected = useMemo(() => [...map.values()], [map]);
|
|
44
|
+
return {
|
|
45
|
+
selected,
|
|
46
|
+
size: map.size,
|
|
47
|
+
isSelected,
|
|
48
|
+
toggle,
|
|
49
|
+
select,
|
|
50
|
+
deselect,
|
|
51
|
+
selectAll,
|
|
52
|
+
clear,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=useStorageSelection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useStorageSelection.js","sourceRoot":"","sources":["../../../src/storage/hooks/useStorageSelection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AA4BvD;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB;IACjC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,QAAQ,CAC5B,GAAG,EAAE,CAAC,IAAI,GAAG,EAAE,CAChB,CAAC;IAEF,MAAM,UAAU,GAAG,WAAW,CAC5B,CAAC,QAAgB,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,EACvC,CAAC,GAAG,CAAC,CACN,CAAC;IAEF,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,KAA4B,EAAE,EAAE;QAC1D,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;YACd,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC;gBAAE,OAAO,IAAI,CAAC;YAC1C,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;YAC3B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YAChC,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,QAAgB,EAAE,EAAE;QAChD,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;YACd,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;gBAAE,OAAO,IAAI,CAAC;YACrC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;YAC3B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACtB,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,KAA4B,EAAE,EAAE;QAC1D,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;YACd,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;YAC3B,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC;gBAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;;gBACrD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YACrC,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,OAAgC,EAAE,EAAE;QACjE,MAAM,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvD,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IAEvD,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAEzD,OAAO;QACL,QAAQ;QACR,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,UAAU;QACV,MAAM;QACN,MAAM;QACN,QAAQ;QACR,SAAS;QACT,KAAK;KACN,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from './hooks/index.js';
|
|
2
|
+
export { StorageApiProvider, useStorageApi, type StorageApi } from './storageApi.js';
|
|
3
|
+
export { PathBreadcrumb, type PathBreadcrumbProps, } from './components/PathBreadcrumb.js';
|
|
4
|
+
export { ObjectBrowser, type ObjectBrowserProps, } from './components/ObjectBrowser.js';
|
|
5
|
+
export { UploadDropzone, type UploadDropzoneProps, type DroppedFile, } from './components/UploadDropzone.js';
|
|
6
|
+
export { splitStorageName, parseCopyCounter, resolveCollision, planBatchNames, } from './collisionRename.js';
|
|
7
|
+
export { expandPathChain, initialPendingPrefixes, pendingPrefixReducer, pendingChildFolders, isPendingPrefix, folderInputError, type PendingPrefixState, type PendingPrefixAction, } from './pendingPrefixes.js';
|
|
8
|
+
export { defaultStoragePreviews, imagePreview, textPreview, selectStoragePreview, TEXT_PREVIEW_MAX_BYTES, type StoragePreview, type StoragePreviewContext, } from './previews.js';
|
|
9
|
+
export { ObjectInspector, type ObjectInspectorProps, } from './components/ObjectInspector.js';
|
|
10
|
+
export { DeleteSelectionWithConfirm, type DeleteSelectionWithConfirmProps, } from './components/DeleteSelectionWithConfirm.js';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AAIjC,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGrF,OAAO,EACL,cAAc,EACd,KAAK,mBAAmB,GACzB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,aAAa,EACb,KAAK,kBAAkB,GACxB,MAAM,+BAA+B,CAAC;AAGvC,OAAO,EACL,cAAc,EACd,KAAK,mBAAmB,EACxB,KAAK,WAAW,GACjB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,GACf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,GACzB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EACL,sBAAsB,EACtB,YAAY,EACZ,WAAW,EACX,oBAAoB,EACpB,sBAAsB,EACtB,KAAK,cAAc,EACnB,KAAK,qBAAqB,GAC3B,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,eAAe,EACf,KAAK,oBAAoB,GAC1B,MAAM,iCAAiC,CAAC;AAGzC,OAAO,EACL,0BAA0B,EAC1B,KAAK,+BAA+B,GACrC,MAAM,4CAA4C,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export * from './hooks/index.js';
|
|
2
|
+
// Injectable Storage API bundle (Pyric Studio data-backend swap): defaults to
|
|
3
|
+
// in-process `pyric/storage`; a consumer can provide the SharedWorker client.
|
|
4
|
+
export { StorageApiProvider, useStorageApi } from './storageApi.js';
|
|
5
|
+
// M2: navigation shell
|
|
6
|
+
export { PathBreadcrumb, } from './components/PathBreadcrumb.js';
|
|
7
|
+
export { ObjectBrowser, } from './components/ObjectBrowser.js';
|
|
8
|
+
// M3: upload
|
|
9
|
+
export { UploadDropzone, } from './components/UploadDropzone.js';
|
|
10
|
+
export { splitStorageName, parseCopyCounter, resolveCollision, planBatchNames, } from './collisionRename.js';
|
|
11
|
+
export { expandPathChain, initialPendingPrefixes, pendingPrefixReducer, pendingChildFolders, isPendingPrefix, folderInputError, } from './pendingPrefixes.js';
|
|
12
|
+
// M4: inspection, content-type preview registry + inspector
|
|
13
|
+
export { defaultStoragePreviews, imagePreview, textPreview, selectStoragePreview, TEXT_PREVIEW_MAX_BYTES, } from './previews.js';
|
|
14
|
+
export { ObjectInspector, } from './components/ObjectInspector.js';
|
|
15
|
+
// M6: bulk ops
|
|
16
|
+
export { DeleteSelectionWithConfirm, } from './components/DeleteSelectionWithConfirm.js';
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AAEjC,8EAA8E;AAC9E,8EAA8E;AAC9E,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAmB,MAAM,iBAAiB,CAAC;AAErF,uBAAuB;AACvB,OAAO,EACL,cAAc,GAEf,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,aAAa,GAEd,MAAM,+BAA+B,CAAC;AAEvC,aAAa;AACb,OAAO,EACL,cAAc,GAGf,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,GACf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,GAGjB,MAAM,sBAAsB,CAAC;AAE9B,4DAA4D;AAC5D,OAAO,EACL,sBAAsB,EACtB,YAAY,EACZ,WAAW,EACX,oBAAoB,EACpB,sBAAsB,GAGvB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,eAAe,GAEhB,MAAM,iCAAiC,CAAC;AAEzC,eAAe;AACf,OAAO,EACL,0BAA0B,GAE3B,MAAM,4CAA4C,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pending (not-yet-materialized) folder prefixes — pure reducer, no React.
|
|
3
|
+
*
|
|
4
|
+
* MECHANISM DECISION (create-folder). GCS has no real folders: a
|
|
5
|
+
* "folder" exists only as a shared prefix of object names. Two honest
|
|
6
|
+
* ways to let a user create one before it contains anything:
|
|
7
|
+
*
|
|
8
|
+
* a) write a zero-byte `<path>/` placeholder object (the emulator-UI
|
|
9
|
+
* convention — `useObjectUpload.createFolder` does this): the
|
|
10
|
+
* folder survives reloads, but every created folder deposits a
|
|
11
|
+
* phantom object in the sandbox store, and the trailing-slash ref
|
|
12
|
+
* is sandbox-only (prod `ref()` rejects it, and the Studio worker
|
|
13
|
+
* `StorageApi` path has no channel for it at all);
|
|
14
|
+
*
|
|
15
|
+
* b) hold the created prefix as CLIENT-SIDE PENDING STATE and let the
|
|
16
|
+
* first upload into it materialize it for real. The store stays
|
|
17
|
+
* byte-for-byte clean — nothing is written until a file is — at
|
|
18
|
+
* the cost that a created-then-abandoned empty folder disappears
|
|
19
|
+
* on reload.
|
|
20
|
+
*
|
|
21
|
+
* Studio's create-folder flow uses (b): the sandbox store is the
|
|
22
|
+
* user's actual data and must not accrue placeholder objects, and the
|
|
23
|
+
* disappearing-empty-folder tradeoff is acceptable BECAUSE the UI
|
|
24
|
+
* labels pending rows as session-only ("empty" badge + empty-state
|
|
25
|
+
* copy in `StoragePane`). (a) remains available to consumers who want
|
|
26
|
+
* persistent empty folders in sandbox-only setups.
|
|
27
|
+
*
|
|
28
|
+
* State is a sorted list of normalized bucket-rooted prefix paths (no
|
|
29
|
+
* trailing slashes). Creating `stuff/things/cool` expands the whole
|
|
30
|
+
* chain — `stuff`, `stuff/things`, `stuff/things/cool` — so every
|
|
31
|
+
* ancestor level shows the folder while browsing (VS Code-style nested
|
|
32
|
+
* create). A successful upload MATERIALIZES its destination folder:
|
|
33
|
+
* the chain up to that folder leaves pending state (the real listing
|
|
34
|
+
* now surfaces those prefixes); pending descendants of other branches
|
|
35
|
+
* stay.
|
|
36
|
+
*/
|
|
37
|
+
/** Sorted, deduped, normalized pending prefix paths. */
|
|
38
|
+
export type PendingPrefixState = readonly string[];
|
|
39
|
+
export type PendingPrefixAction =
|
|
40
|
+
/** Create a folder at `path` (absolute, bucket-rooted; nested paths
|
|
41
|
+
* allowed) — adds the full ancestor chain. */
|
|
42
|
+
{
|
|
43
|
+
type: 'create';
|
|
44
|
+
path: string;
|
|
45
|
+
}
|
|
46
|
+
/** An object now exists directly under `path`: drop `path` and its
|
|
47
|
+
* ancestors from pending (they are real prefixes now). */
|
|
48
|
+
| {
|
|
49
|
+
type: 'materialize';
|
|
50
|
+
path: string;
|
|
51
|
+
} | {
|
|
52
|
+
type: 'clear';
|
|
53
|
+
};
|
|
54
|
+
/** `'a/b/c'` → `['a', 'a/b', 'a/b/c']`; `''` → `[]`. */
|
|
55
|
+
export declare function expandPathChain(path: string): string[];
|
|
56
|
+
export declare const initialPendingPrefixes: PendingPrefixState;
|
|
57
|
+
export declare function pendingPrefixReducer(state: PendingPrefixState, action: PendingPrefixAction): PendingPrefixState;
|
|
58
|
+
/** Direct-child folder NAMES pending under `parentPath` (`''` = root),
|
|
59
|
+
* sorted. The chain expansion guarantees every level is present, so a
|
|
60
|
+
* simple parent match is exact. */
|
|
61
|
+
export declare function pendingChildFolders(state: PendingPrefixState, parentPath: string): string[];
|
|
62
|
+
/** Whether `path` itself is a pending (session-only) folder. */
|
|
63
|
+
export declare function isPendingPrefix(state: PendingPrefixState, path: string): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Validate a create-folder input (relative to the current folder;
|
|
66
|
+
* nested `a/b/c` allowed — VS Code semantics). Returns an error
|
|
67
|
+
* message or `null` when valid. Normalization tolerates stray/repeat
|
|
68
|
+
* slashes; `.`/`..` segments are rejected (GCS object names have no
|
|
69
|
+
* dot-segment semantics — accepting them would create unreachable
|
|
70
|
+
* names).
|
|
71
|
+
*/
|
|
72
|
+
export declare function folderInputError(input: string): string | null;
|
|
73
|
+
//# sourceMappingURL=pendingPrefixes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pendingPrefixes.d.ts","sourceRoot":"","sources":["../../src/storage/pendingPrefixes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAIH,wDAAwD;AACxD,MAAM,MAAM,kBAAkB,GAAG,SAAS,MAAM,EAAE,CAAC;AAEnD,MAAM,MAAM,mBAAmB;AAC7B;+CAC+C;AAC7C;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AAClC;2DAC2D;GACzD;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAEtB,wDAAwD;AACxD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAKtD;AAED,eAAO,MAAM,sBAAsB,EAAE,kBAAuB,CAAC;AAE7D,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,kBAAkB,EACzB,MAAM,EAAE,mBAAmB,GAC1B,kBAAkB,CAgBpB;AAED;;oCAEoC;AACpC,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,kBAAkB,EACzB,UAAU,EAAE,MAAM,GACjB,MAAM,EAAE,CAMV;AAED,gEAAgE;AAChE,wBAAgB,eAAe,CAAC,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAEhF;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQ7D"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pending (not-yet-materialized) folder prefixes — pure reducer, no React.
|
|
3
|
+
*
|
|
4
|
+
* MECHANISM DECISION (create-folder). GCS has no real folders: a
|
|
5
|
+
* "folder" exists only as a shared prefix of object names. Two honest
|
|
6
|
+
* ways to let a user create one before it contains anything:
|
|
7
|
+
*
|
|
8
|
+
* a) write a zero-byte `<path>/` placeholder object (the emulator-UI
|
|
9
|
+
* convention — `useObjectUpload.createFolder` does this): the
|
|
10
|
+
* folder survives reloads, but every created folder deposits a
|
|
11
|
+
* phantom object in the sandbox store, and the trailing-slash ref
|
|
12
|
+
* is sandbox-only (prod `ref()` rejects it, and the Studio worker
|
|
13
|
+
* `StorageApi` path has no channel for it at all);
|
|
14
|
+
*
|
|
15
|
+
* b) hold the created prefix as CLIENT-SIDE PENDING STATE and let the
|
|
16
|
+
* first upload into it materialize it for real. The store stays
|
|
17
|
+
* byte-for-byte clean — nothing is written until a file is — at
|
|
18
|
+
* the cost that a created-then-abandoned empty folder disappears
|
|
19
|
+
* on reload.
|
|
20
|
+
*
|
|
21
|
+
* Studio's create-folder flow uses (b): the sandbox store is the
|
|
22
|
+
* user's actual data and must not accrue placeholder objects, and the
|
|
23
|
+
* disappearing-empty-folder tradeoff is acceptable BECAUSE the UI
|
|
24
|
+
* labels pending rows as session-only ("empty" badge + empty-state
|
|
25
|
+
* copy in `StoragePane`). (a) remains available to consumers who want
|
|
26
|
+
* persistent empty folders in sandbox-only setups.
|
|
27
|
+
*
|
|
28
|
+
* State is a sorted list of normalized bucket-rooted prefix paths (no
|
|
29
|
+
* trailing slashes). Creating `stuff/things/cool` expands the whole
|
|
30
|
+
* chain — `stuff`, `stuff/things`, `stuff/things/cool` — so every
|
|
31
|
+
* ancestor level shows the folder while browsing (VS Code-style nested
|
|
32
|
+
* create). A successful upload MATERIALIZES its destination folder:
|
|
33
|
+
* the chain up to that folder leaves pending state (the real listing
|
|
34
|
+
* now surfaces those prefixes); pending descendants of other branches
|
|
35
|
+
* stay.
|
|
36
|
+
*/
|
|
37
|
+
import { normalizeStoragePath } from './hooks/usePathState.js';
|
|
38
|
+
/** `'a/b/c'` → `['a', 'a/b', 'a/b/c']`; `''` → `[]`. */
|
|
39
|
+
export function expandPathChain(path) {
|
|
40
|
+
const normalized = normalizeStoragePath(path);
|
|
41
|
+
if (normalized === '')
|
|
42
|
+
return [];
|
|
43
|
+
const segments = normalized.split('/');
|
|
44
|
+
return segments.map((_, i) => segments.slice(0, i + 1).join('/'));
|
|
45
|
+
}
|
|
46
|
+
export const initialPendingPrefixes = [];
|
|
47
|
+
export function pendingPrefixReducer(state, action) {
|
|
48
|
+
switch (action.type) {
|
|
49
|
+
case 'create': {
|
|
50
|
+
const chain = expandPathChain(action.path).filter((p) => !state.includes(p));
|
|
51
|
+
if (chain.length === 0)
|
|
52
|
+
return state;
|
|
53
|
+
return [...state, ...chain].sort();
|
|
54
|
+
}
|
|
55
|
+
case 'materialize': {
|
|
56
|
+
const real = new Set(expandPathChain(action.path));
|
|
57
|
+
if (real.size === 0)
|
|
58
|
+
return state;
|
|
59
|
+
const next = state.filter((p) => !real.has(p));
|
|
60
|
+
return next.length === state.length ? state : next;
|
|
61
|
+
}
|
|
62
|
+
case 'clear':
|
|
63
|
+
return state.length === 0 ? state : initialPendingPrefixes;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/** Direct-child folder NAMES pending under `parentPath` (`''` = root),
|
|
67
|
+
* sorted. The chain expansion guarantees every level is present, so a
|
|
68
|
+
* simple parent match is exact. */
|
|
69
|
+
export function pendingChildFolders(state, parentPath) {
|
|
70
|
+
const parent = normalizeStoragePath(parentPath);
|
|
71
|
+
const prefix = parent === '' ? '' : `${parent}/`;
|
|
72
|
+
return state
|
|
73
|
+
.filter((p) => p.startsWith(prefix) && p !== parent && !p.slice(prefix.length).includes('/'))
|
|
74
|
+
.map((p) => p.slice(prefix.length));
|
|
75
|
+
}
|
|
76
|
+
/** Whether `path` itself is a pending (session-only) folder. */
|
|
77
|
+
export function isPendingPrefix(state, path) {
|
|
78
|
+
return state.includes(normalizeStoragePath(path));
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Validate a create-folder input (relative to the current folder;
|
|
82
|
+
* nested `a/b/c` allowed — VS Code semantics). Returns an error
|
|
83
|
+
* message or `null` when valid. Normalization tolerates stray/repeat
|
|
84
|
+
* slashes; `.`/`..` segments are rejected (GCS object names have no
|
|
85
|
+
* dot-segment semantics — accepting them would create unreachable
|
|
86
|
+
* names).
|
|
87
|
+
*/
|
|
88
|
+
export function folderInputError(input) {
|
|
89
|
+
const normalized = normalizeStoragePath(input);
|
|
90
|
+
if (normalized === '')
|
|
91
|
+
return 'Enter a folder name.';
|
|
92
|
+
const segments = normalized.split('/');
|
|
93
|
+
if (segments.some((s) => s === '.' || s === '..')) {
|
|
94
|
+
return 'Folder names may not be "." or "..".';
|
|
95
|
+
}
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=pendingPrefixes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pendingPrefixes.js","sourceRoot":"","sources":["../../src/storage/pendingPrefixes.ts"],"names":[],"mappings":"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"}
|