@pyric/ui 0.1.0-alpha.10
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/LICENSE +216 -0
- 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 +62 -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 +63 -0
- package/dist/firestore/components/DocumentList.d.ts.map +1 -0
- package/dist/firestore/components/DocumentList.js +53 -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 +29 -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 +61 -0
- package/dist/firestore/hooks/useDocumentEditor.d.ts.map +1 -0
- package/dist/firestore/hooks/useDocumentEditor.js +71 -0
- package/dist/firestore/hooks/useDocumentEditor.js.map +1 -0
- package/dist/firestore/hooks/useDocumentList.d.ts +50 -0
- package/dist/firestore/hooks/useDocumentList.d.ts.map +1 -0
- package/dist/firestore/hooks/useDocumentList.js +162 -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 +36 -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 +35 -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 +21 -0
- package/dist/firestore/index.d.ts.map +1 -0
- package/dist/firestore/index.js +29 -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 +201 -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 +115 -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/firestore/valueEquality.d.ts +4 -0
- package/dist/firestore/valueEquality.d.ts.map +1 -0
- package/dist/firestore/valueEquality.js +44 -0
- package/dist/firestore/valueEquality.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/hooks/useUpdateHighlights.d.ts +18 -0
- package/dist/primitives/hooks/useUpdateHighlights.d.ts.map +1 -0
- package/dist/primitives/hooks/useUpdateHighlights.js +84 -0
- package/dist/primitives/hooks/useUpdateHighlights.js.map +1 -0
- package/dist/primitives/index.d.ts +11 -0
- package/dist/primitives/index.d.ts.map +1 -0
- package/dist/primitives/index.js +11 -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 +104 -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 +33 -0
- package/dist/rtdb/hooks/useRtdbTree.d.ts.map +1 -0
- package/dist/rtdb/hooks/useRtdbTree.js +67 -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 +50 -0
- package/dist/rtdb/values.d.ts.map +1 -0
- package/dist/rtdb/values.js +186 -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 +66 -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 +78 -0
- package/dist/storage/components/ObjectBrowser.d.ts.map +1 -0
- package/dist/storage/components/ObjectBrowser.js +60 -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 +20 -0
- package/dist/storage/folderPlaceholder.d.ts.map +1 -0
- package/dist/storage/folderPlaceholder.js +34 -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 +105 -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 +74 -0
- package/dist/storage/hooks/useStorageDelete.d.ts.map +1 -0
- package/dist/storage/hooks/useStorageDelete.js +120 -0
- package/dist/storage/hooks/useStorageDelete.js.map +1 -0
- package/dist/storage/hooks/useStorageList.d.ts +72 -0
- package/dist/storage/hooks/useStorageList.d.ts.map +1 -0
- package/dist/storage/hooks/useStorageList.js +164 -0
- package/dist/storage/hooks/useStorageList.js.map +1 -0
- package/dist/storage/hooks/useStorageObject.d.ts +33 -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 +116 -0
- package/dist/storage/hooks/useStorageRulesGate.d.ts.map +1 -0
- package/dist/storage/hooks/useStorageRulesGate.js +150 -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 +77 -0
- package/dist/storage/pendingPrefixes.d.ts.map +1 -0
- package/dist/storage/pendingPrefixes.js +104 -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 +20 -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 +25 -0
- package/dist/traffic/components/TrafficGroupRow.js.map +1 -0
- package/dist/traffic/components/TrafficLineChart.d.ts +37 -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 +88 -0
- package/dist/traffic/components/TrafficTimeline.d.ts.map +1 -0
- package/dist/traffic/components/TrafficTimeline.js +86 -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 +127 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { type RuleEvaluation, type PathResolutionTrace } from 'pyric/rules/internal';
|
|
2
|
+
import type { FirestoreMethod } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* The captured request a host re-runs through the simulator to produce a
|
|
5
|
+
* `Denial`. A subset of the simulator's `TestCase` — no expectation /
|
|
6
|
+
* description (those are test-runner concerns); the host already knows
|
|
7
|
+
* the request was denied.
|
|
8
|
+
*/
|
|
9
|
+
export interface DenialRequest {
|
|
10
|
+
method: FirestoreMethod;
|
|
11
|
+
/** Resource path, e.g. `notes/3agHoZHZ`. */
|
|
12
|
+
path: string;
|
|
13
|
+
/** `request.auth` — `null`/omitted for unauthenticated. */
|
|
14
|
+
auth?: {
|
|
15
|
+
uid: string;
|
|
16
|
+
token?: Record<string, unknown>;
|
|
17
|
+
} | null;
|
|
18
|
+
/** `request.resource.data` — for writes. */
|
|
19
|
+
requestData?: Record<string, unknown>;
|
|
20
|
+
/** `resource.data` — the existing document. */
|
|
21
|
+
resourceData?: Record<string, unknown> | null;
|
|
22
|
+
/** Override `request.time` (ISO-8601). Defaults to wallclock. */
|
|
23
|
+
requestTime?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface DenialTrace {
|
|
26
|
+
/** Per allow-rule evaluation, in source order. Empty for no-match denials. */
|
|
27
|
+
evaluation: RuleEvaluation[];
|
|
28
|
+
/** Which `match` blocks the resolver tried — present for no-match denials. */
|
|
29
|
+
pathResolution?: PathResolutionTrace;
|
|
30
|
+
/** True when the simulator could parse + evaluate. False on a parse error. */
|
|
31
|
+
ok: boolean;
|
|
32
|
+
/** Populated when `ok` is false (e.g. the rules source failed to parse). */
|
|
33
|
+
error?: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Re-run a captured (denied) Firestore request through the local rules
|
|
37
|
+
* simulator — tracing is always on there — and return the structured
|
|
38
|
+
* trace a `DenialInspector` renders.
|
|
39
|
+
*
|
|
40
|
+
* Memoized on `(request, rulesSource)`; the simulator is pure and
|
|
41
|
+
* in-process, so this is cheap to call on every render. A host produces
|
|
42
|
+
* a `Denial` by spreading the request fields alongside the result:
|
|
43
|
+
*
|
|
44
|
+
* ```ts
|
|
45
|
+
* const { evaluation, pathResolution } = useDenialTrace(req, rules);
|
|
46
|
+
* const denial: Denial = { ...req, decision: 'DENY', rulesSource: rules,
|
|
47
|
+
* at, evaluation, pathResolution };
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare function useDenialTrace(request: DenialRequest, rulesSource: string): DenialTrace;
|
|
51
|
+
//# sourceMappingURL=useDenialTrace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDenialTrace.d.ts","sourceRoot":"","sources":["../../../src/rules/hooks/useDenialTrace.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACzB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,eAAe,CAAC;IACxB,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,IAAI,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,IAAI,CAAC;IAC/D,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC9C,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,8EAA8E;IAC9E,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,8EAA8E;IAC9E,cAAc,CAAC,EAAE,mBAAmB,CAAC;IACrC,8EAA8E;IAC9E,EAAE,EAAE,OAAO,CAAC;IACZ,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAkBD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,aAAa,EACtB,WAAW,EAAE,MAAM,GAClB,WAAW,CAyBb"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { SimulateFirestoreRulesHandler, } from 'pyric/rules/internal';
|
|
3
|
+
function toTestCase(req) {
|
|
4
|
+
return {
|
|
5
|
+
description: `denial-inspector: ${req.method} ${req.path}`,
|
|
6
|
+
// The request was denied — we re-run it expecting DENY so the
|
|
7
|
+
// simulator's PASSED/FAILED bookkeeping stays self-consistent. The
|
|
8
|
+
// trace (which we actually consume) is independent of expectation.
|
|
9
|
+
expectation: 'DENY',
|
|
10
|
+
method: req.method,
|
|
11
|
+
path: req.path,
|
|
12
|
+
auth: req.auth ?? null,
|
|
13
|
+
...(req.requestData !== undefined ? { data: req.requestData } : {}),
|
|
14
|
+
...(req.resourceData != null ? { resource: req.resourceData } : {}),
|
|
15
|
+
...(req.requestTime !== undefined ? { requestTime: req.requestTime } : {}),
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Re-run a captured (denied) Firestore request through the local rules
|
|
20
|
+
* simulator — tracing is always on there — and return the structured
|
|
21
|
+
* trace a `DenialInspector` renders.
|
|
22
|
+
*
|
|
23
|
+
* Memoized on `(request, rulesSource)`; the simulator is pure and
|
|
24
|
+
* in-process, so this is cheap to call on every render. A host produces
|
|
25
|
+
* a `Denial` by spreading the request fields alongside the result:
|
|
26
|
+
*
|
|
27
|
+
* ```ts
|
|
28
|
+
* const { evaluation, pathResolution } = useDenialTrace(req, rules);
|
|
29
|
+
* const denial: Denial = { ...req, decision: 'DENY', rulesSource: rules,
|
|
30
|
+
* at, evaluation, pathResolution };
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export function useDenialTrace(request, rulesSource) {
|
|
34
|
+
// Stable identity key — `request` is often a fresh object literal each
|
|
35
|
+
// render, so memoize on its content, not its reference.
|
|
36
|
+
const key = useMemo(() => JSON.stringify(request), [request]);
|
|
37
|
+
return useMemo(() => {
|
|
38
|
+
const handler = new SimulateFirestoreRulesHandler();
|
|
39
|
+
const result = handler.simulate(rulesSource, [toTestCase(request)]);
|
|
40
|
+
if (!result.success) {
|
|
41
|
+
return { evaluation: [], ok: false, error: result.error.message };
|
|
42
|
+
}
|
|
43
|
+
const first = result.data.results[0];
|
|
44
|
+
if (!first) {
|
|
45
|
+
return { evaluation: [], ok: false, error: 'simulator returned no result' };
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
evaluation: first.trace,
|
|
49
|
+
...(first.pathResolution ? { pathResolution: first.pathResolution } : {}),
|
|
50
|
+
ok: true,
|
|
51
|
+
};
|
|
52
|
+
// `key` captures the content of `request`; `request` itself is read
|
|
53
|
+
// inside but intentionally excluded so a new-but-equal object literal
|
|
54
|
+
// doesn't re-run the simulator.
|
|
55
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
56
|
+
}, [key, rulesSource]);
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=useDenialTrace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDenialTrace.js","sourceRoot":"","sources":["../../../src/rules/hooks/useDenialTrace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EACL,6BAA6B,GAI9B,MAAM,sBAAsB,CAAC;AAkC9B,SAAS,UAAU,CAAC,GAAkB;IACpC,OAAO;QACL,WAAW,EAAE,qBAAqB,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE;QAC1D,8DAA8D;QAC9D,mEAAmE;QACnE,mEAAmE;QACnE,WAAW,EAAE,MAAM;QACnB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,IAAI;QACtB,GAAG,CAAC,GAAG,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnE,GAAG,CAAC,GAAG,CAAC,YAAY,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnE,GAAG,CAAC,GAAG,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC3E,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,cAAc,CAC5B,OAAsB,EACtB,WAAmB;IAEnB,uEAAuE;IACvE,wDAAwD;IACxD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAE9D,OAAO,OAAO,CAAc,GAAG,EAAE;QAC/B,MAAM,OAAO,GAAG,IAAI,6BAA6B,EAAE,CAAC;QACpD,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACpE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QACpE,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACrC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,8BAA8B,EAAE,CAAC;QAC9E,CAAC;QACD,OAAO;YACL,UAAU,EAAE,KAAK,CAAC,KAAK;YACvB,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzE,EAAE,EAAE,IAAI;SACT,CAAC;QACF,oEAAoE;QACpE,sEAAsE;QACtE,gCAAgC;QAChC,uDAAuD;IACzD,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@pyric/ui/rules` — headless components for Firestore rules debugging.
|
|
3
|
+
*
|
|
4
|
+
* The Studio "Debug a denial" screen (`mocks/c-debug.html`) as a
|
|
5
|
+
* props-driven, zero-styling component: `DenialInspector` renders *why*
|
|
6
|
+
* one request was denied (reason, line-marked rule, expression
|
|
7
|
+
* step-through, data in scope, path resolution) and exposes a re-run /
|
|
8
|
+
* verify loop. Grounded entirely in the `pyric/rules` simulator trace —
|
|
9
|
+
* no engine work, pure presentation.
|
|
10
|
+
*/
|
|
11
|
+
export * from './hooks/index.js';
|
|
12
|
+
export * from './components/index.js';
|
|
13
|
+
export type { Denial, DenialLens, DenialInspectorProps, LineVerdict, RuleEvaluation, PathResolutionTrace, PathResolutionEntry, ExprTraceEntry, FirestoreMethod, } from './types.js';
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AAEtC,YAAY,EACV,MAAM,EACN,UAAU,EACV,oBAAoB,EACpB,WAAW,EACX,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACd,eAAe,GAChB,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@pyric/ui/rules` — headless components for Firestore rules debugging.
|
|
3
|
+
*
|
|
4
|
+
* The Studio "Debug a denial" screen (`mocks/c-debug.html`) as a
|
|
5
|
+
* props-driven, zero-styling component: `DenialInspector` renders *why*
|
|
6
|
+
* one request was denied (reason, line-marked rule, expression
|
|
7
|
+
* step-through, data in scope, path resolution) and exposes a re-run /
|
|
8
|
+
* verify loop. Grounded entirely in the `pyric/rules` simulator trace —
|
|
9
|
+
* no engine work, pure presentation.
|
|
10
|
+
*/
|
|
11
|
+
export * from './hooks/index.js';
|
|
12
|
+
export * from './components/index.js';
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { RuleEvaluation, PathResolutionTrace, PathResolutionEntry, ExprTraceEntry, FirestoreMethod } from 'pyric/rules/internal';
|
|
2
|
+
export type { RuleEvaluation, PathResolutionTrace, PathResolutionEntry, ExprTraceEntry, FirestoreMethod, };
|
|
3
|
+
/**
|
|
4
|
+
* The lens a request was issued under, mirroring the Studio's identity
|
|
5
|
+
* model:
|
|
6
|
+
* - `'admin'` — the admin handle (bypasses rules in production,
|
|
7
|
+
* shown here for provenance only)
|
|
8
|
+
* - `{ as: uid }` — acting as a specific signed-in user
|
|
9
|
+
* - `'app-session'` — the ambient app session (whoever is signed in
|
|
10
|
+
* in the running preview)
|
|
11
|
+
*/
|
|
12
|
+
export type DenialLens = 'admin' | {
|
|
13
|
+
as: string;
|
|
14
|
+
} | 'app-session';
|
|
15
|
+
/**
|
|
16
|
+
* One denied Firestore request, enriched with the simulator trace.
|
|
17
|
+
*
|
|
18
|
+
* The live denial *event* carries only `debugMessages`; the rich trace
|
|
19
|
+
* (`evaluation` / `pathResolution`) is produced by re-running the
|
|
20
|
+
* simulator (tracing always on) against the captured request. Build one
|
|
21
|
+
* with `useDenialTrace(request, rulesSource)` then spread the captured
|
|
22
|
+
* request fields alongside.
|
|
23
|
+
*/
|
|
24
|
+
export interface Denial {
|
|
25
|
+
method: FirestoreMethod;
|
|
26
|
+
/** Resource path, e.g. `notes/3agHoZHZ`. */
|
|
27
|
+
path: string;
|
|
28
|
+
/** `request.auth` — `null` for an unauthenticated request. */
|
|
29
|
+
auth: {
|
|
30
|
+
uid: string;
|
|
31
|
+
token: Record<string, unknown>;
|
|
32
|
+
} | null;
|
|
33
|
+
/** Identity lens the request was issued under. */
|
|
34
|
+
lens?: DenialLens;
|
|
35
|
+
/** `request.resource.data` — present for writes. */
|
|
36
|
+
requestData?: Record<string, unknown>;
|
|
37
|
+
/** `resource.data` — the existing document, `null` when absent. */
|
|
38
|
+
resourceData?: Record<string, unknown> | null;
|
|
39
|
+
/** Capture time (epoch ms). */
|
|
40
|
+
at: number;
|
|
41
|
+
/** `firestore.rules` source the request was evaluated against. */
|
|
42
|
+
rulesSource: string;
|
|
43
|
+
decision: 'DENY';
|
|
44
|
+
/**
|
|
45
|
+
* Per allow-rule evaluation, in source order. Each entry carries the
|
|
46
|
+
* `line`, `verdict`, `conditionText`, and `expressionTrace`.
|
|
47
|
+
*/
|
|
48
|
+
evaluation: RuleEvaluation[];
|
|
49
|
+
/**
|
|
50
|
+
* Path-resolution attempts — present for no-match (default-deny)
|
|
51
|
+
* denials, where no `allow` rule was evaluated because no `match`
|
|
52
|
+
* block covered the path.
|
|
53
|
+
*/
|
|
54
|
+
pathResolution?: PathResolutionTrace;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Per-line verdict for the rule-source view. `deny` is the deciding
|
|
58
|
+
* allow line; `skip` is an allow line whose operations don't include
|
|
59
|
+
* the request method ("not checked"); `allow` is any other allow line.
|
|
60
|
+
* Non-allow lines (match/braces/comments) get no verdict.
|
|
61
|
+
*/
|
|
62
|
+
export type LineVerdict = 'deny' | 'allow' | 'skip';
|
|
63
|
+
export interface DenialInspectorProps {
|
|
64
|
+
denial: Denial;
|
|
65
|
+
/** Sibling denials produced by the same rule. */
|
|
66
|
+
cluster?: Denial[];
|
|
67
|
+
/** Re-run the request under `{ mode: 'as', uid }`. */
|
|
68
|
+
onRerunAs?(uid: string): void;
|
|
69
|
+
/** Re-run against an edited ruleset (a branch). */
|
|
70
|
+
onTestEditedRule?(): void;
|
|
71
|
+
/** A cluster sibling was selected. */
|
|
72
|
+
onSelectCluster?(d: Denial): void;
|
|
73
|
+
className?: string;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/rules/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACd,eAAe,EAChB,MAAM,sBAAsB,CAAC;AAI9B,YAAY,EACV,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACd,eAAe,GAChB,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,aAAa,CAAC;AAElE;;;;;;;;GAQG;AACH,MAAM,WAAW,MAAM;IAErB,MAAM,EAAE,eAAe,CAAC;IACxB,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,8DAA8D;IAC9D,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,IAAI,CAAC;IAC7D,kDAAkD;IAClD,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,oDAAoD;IACpD,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC9C,+BAA+B;IAC/B,EAAE,EAAE,MAAM,CAAC;IAGX,kEAAkE;IAClE,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B;;;;OAIG;IACH,cAAc,CAAC,EAAE,mBAAmB,CAAC;CACtC;AAED;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAEpD,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,sDAAsD;IACtD,SAAS,CAAC,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,mDAAmD;IACnD,gBAAgB,CAAC,IAAI,IAAI,CAAC;IAC1B,sCAAsC;IACtC,eAAe,CAAC,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/rules/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OS-copy collision renaming for uploads/drops — pure logic, no React.
|
|
3
|
+
*
|
|
4
|
+
* THE RULE (mirrors macOS Finder's "keep both" counter semantics, with
|
|
5
|
+
* the Windows-style ` (n)` spelling the spec pins):
|
|
6
|
+
*
|
|
7
|
+
* 1. Split the name into `stem + ext`. The extension is the suffix from
|
|
8
|
+
* the LAST dot, only when that dot is neither the first character nor
|
|
9
|
+
* the last: `photo.png` → `photo` + `.png`; `archive.tar.gz` →
|
|
10
|
+
* `archive.tar` + `.gz`; dotfiles (`.gitignore`) and trailing-dot
|
|
11
|
+
* names (`notes.`) have NO extension — the whole name is the stem;
|
|
12
|
+
* extensionless names (`Makefile`) likewise.
|
|
13
|
+
* 2. If the stem already ends in a ` (n)` counter (single space, plain
|
|
14
|
+
* decimal integer), the counter is INCREMENTED, not nested:
|
|
15
|
+
* `photo (1).png` colliding becomes `photo (2).png`, never
|
|
16
|
+
* `photo (1) (1).png`. (`photo (1) (2).png` → base `photo (1)`,
|
|
17
|
+
* counter 2 → `photo (1) (3).png`: only the final counter moves.)
|
|
18
|
+
* 3. Otherwise the first candidate is ` (1)`: `photo.png` →
|
|
19
|
+
* `photo (1).png`.
|
|
20
|
+
* 4. Candidates increment until one is not taken.
|
|
21
|
+
*
|
|
22
|
+
* A name that isn't taken is returned unchanged — the renamer only
|
|
23
|
+
* fires on collision.
|
|
24
|
+
*/
|
|
25
|
+
/** `name` split as the rule defines: `ext` includes the leading dot,
|
|
26
|
+
* or is `''` when the name has no extension (dotfiles, trailing dots,
|
|
27
|
+
* extensionless names). */
|
|
28
|
+
export declare function splitStorageName(name: string): {
|
|
29
|
+
stem: string;
|
|
30
|
+
ext: string;
|
|
31
|
+
};
|
|
32
|
+
/** Trailing ` (n)` counter: `photo (3)` → base `photo`, counter 3.
|
|
33
|
+
* `counter: null` when the stem carries none. A counter beyond
|
|
34
|
+
* `Number.MAX_SAFE_INTEGER` is treated as plain text (no counter):
|
|
35
|
+
* incrementing it would be lossy — `n + 1 === n` in float land, which
|
|
36
|
+
* turns {@link resolveCollision}'s probe loop into a hang — and the
|
|
37
|
+
* candidate would render in scientific notation anyway. */
|
|
38
|
+
export declare function parseCopyCounter(stem: string): {
|
|
39
|
+
base: string;
|
|
40
|
+
counter: number | null;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Resolve one name against a set of taken sibling names. Returns the
|
|
44
|
+
* name unchanged when free; otherwise the first ` (n)` candidate that
|
|
45
|
+
* is free, per the module rule above.
|
|
46
|
+
*/
|
|
47
|
+
export declare function resolveCollision(name: string, taken: ReadonlySet<string>): string;
|
|
48
|
+
/**
|
|
49
|
+
* Resolve a whole drop/pick batch against the destination folder's
|
|
50
|
+
* existing names, with OS drop semantics: collisions are detected and
|
|
51
|
+
* renamed at the batch's TOP LEVEL only (the names the OS drop
|
|
52
|
+
* "creates" in the destination — a plain file's name, or a dropped
|
|
53
|
+
* folder's root segment). Files inside a dropped folder ride their
|
|
54
|
+
* folder's rename and keep their inner structure untouched — exactly
|
|
55
|
+
* like dropping `photos/` next to an existing `photos/` yields
|
|
56
|
+
* `photos (1)/…` with the contents intact.
|
|
57
|
+
*
|
|
58
|
+
* Within one batch:
|
|
59
|
+
* - all paths sharing a top-level FOLDER segment share its resolution
|
|
60
|
+
* (one dropped folder = one rename), and
|
|
61
|
+
* - top-level FILES resolve individually in order, each claiming its
|
|
62
|
+
* resolved name, so two same-named files in one batch get successive
|
|
63
|
+
* counters.
|
|
64
|
+
*
|
|
65
|
+
* Only the destination's DIRECT children can be checked — that is all
|
|
66
|
+
* the drop target (one `listAll` level) knows. Deeper paths follow GCS
|
|
67
|
+
* overwrite semantics, which the folder-level rename already shields
|
|
68
|
+
* in practice (a colliding folder is renamed wholesale).
|
|
69
|
+
*
|
|
70
|
+
* Returns resolved paths in input order.
|
|
71
|
+
*/
|
|
72
|
+
export declare function planBatchNames(relativePaths: readonly string[], taken: ReadonlySet<string>): string[];
|
|
73
|
+
//# sourceMappingURL=collisionRename.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collisionRename.d.ts","sourceRoot":"","sources":["../../src/storage/collisionRename.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH;;4BAE4B;AAC5B,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAI5E;AAED;;;;;4DAK4D;AAC5D,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAMvF;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,MAAM,CAUjF;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,cAAc,CAC5B,aAAa,EAAE,SAAS,MAAM,EAAE,EAChC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,GACzB,MAAM,EAAE,CAqBV"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OS-copy collision renaming for uploads/drops — pure logic, no React.
|
|
3
|
+
*
|
|
4
|
+
* THE RULE (mirrors macOS Finder's "keep both" counter semantics, with
|
|
5
|
+
* the Windows-style ` (n)` spelling the spec pins):
|
|
6
|
+
*
|
|
7
|
+
* 1. Split the name into `stem + ext`. The extension is the suffix from
|
|
8
|
+
* the LAST dot, only when that dot is neither the first character nor
|
|
9
|
+
* the last: `photo.png` → `photo` + `.png`; `archive.tar.gz` →
|
|
10
|
+
* `archive.tar` + `.gz`; dotfiles (`.gitignore`) and trailing-dot
|
|
11
|
+
* names (`notes.`) have NO extension — the whole name is the stem;
|
|
12
|
+
* extensionless names (`Makefile`) likewise.
|
|
13
|
+
* 2. If the stem already ends in a ` (n)` counter (single space, plain
|
|
14
|
+
* decimal integer), the counter is INCREMENTED, not nested:
|
|
15
|
+
* `photo (1).png` colliding becomes `photo (2).png`, never
|
|
16
|
+
* `photo (1) (1).png`. (`photo (1) (2).png` → base `photo (1)`,
|
|
17
|
+
* counter 2 → `photo (1) (3).png`: only the final counter moves.)
|
|
18
|
+
* 3. Otherwise the first candidate is ` (1)`: `photo.png` →
|
|
19
|
+
* `photo (1).png`.
|
|
20
|
+
* 4. Candidates increment until one is not taken.
|
|
21
|
+
*
|
|
22
|
+
* A name that isn't taken is returned unchanged — the renamer only
|
|
23
|
+
* fires on collision.
|
|
24
|
+
*/
|
|
25
|
+
/** `name` split as the rule defines: `ext` includes the leading dot,
|
|
26
|
+
* or is `''` when the name has no extension (dotfiles, trailing dots,
|
|
27
|
+
* extensionless names). */
|
|
28
|
+
export function splitStorageName(name) {
|
|
29
|
+
const dot = name.lastIndexOf('.');
|
|
30
|
+
if (dot <= 0 || dot === name.length - 1)
|
|
31
|
+
return { stem: name, ext: '' };
|
|
32
|
+
return { stem: name.slice(0, dot), ext: name.slice(dot) };
|
|
33
|
+
}
|
|
34
|
+
/** Trailing ` (n)` counter: `photo (3)` → base `photo`, counter 3.
|
|
35
|
+
* `counter: null` when the stem carries none. A counter beyond
|
|
36
|
+
* `Number.MAX_SAFE_INTEGER` is treated as plain text (no counter):
|
|
37
|
+
* incrementing it would be lossy — `n + 1 === n` in float land, which
|
|
38
|
+
* turns {@link resolveCollision}'s probe loop into a hang — and the
|
|
39
|
+
* candidate would render in scientific notation anyway. */
|
|
40
|
+
export function parseCopyCounter(stem) {
|
|
41
|
+
const m = /^(.*) \((\d+)\)$/.exec(stem);
|
|
42
|
+
if (!m)
|
|
43
|
+
return { base: stem, counter: null };
|
|
44
|
+
const counter = Number(m[2]);
|
|
45
|
+
if (!Number.isSafeInteger(counter))
|
|
46
|
+
return { base: stem, counter: null };
|
|
47
|
+
return { base: m[1], counter };
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Resolve one name against a set of taken sibling names. Returns the
|
|
51
|
+
* name unchanged when free; otherwise the first ` (n)` candidate that
|
|
52
|
+
* is free, per the module rule above.
|
|
53
|
+
*/
|
|
54
|
+
export function resolveCollision(name, taken) {
|
|
55
|
+
if (!taken.has(name))
|
|
56
|
+
return name;
|
|
57
|
+
const { stem, ext } = splitStorageName(name);
|
|
58
|
+
const { base, counter } = parseCopyCounter(stem);
|
|
59
|
+
let n = counter === null ? 1 : counter + 1;
|
|
60
|
+
for (;;) {
|
|
61
|
+
const candidate = `${base} (${n})${ext}`;
|
|
62
|
+
if (!taken.has(candidate))
|
|
63
|
+
return candidate;
|
|
64
|
+
n += 1;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Resolve a whole drop/pick batch against the destination folder's
|
|
69
|
+
* existing names, with OS drop semantics: collisions are detected and
|
|
70
|
+
* renamed at the batch's TOP LEVEL only (the names the OS drop
|
|
71
|
+
* "creates" in the destination — a plain file's name, or a dropped
|
|
72
|
+
* folder's root segment). Files inside a dropped folder ride their
|
|
73
|
+
* folder's rename and keep their inner structure untouched — exactly
|
|
74
|
+
* like dropping `photos/` next to an existing `photos/` yields
|
|
75
|
+
* `photos (1)/…` with the contents intact.
|
|
76
|
+
*
|
|
77
|
+
* Within one batch:
|
|
78
|
+
* - all paths sharing a top-level FOLDER segment share its resolution
|
|
79
|
+
* (one dropped folder = one rename), and
|
|
80
|
+
* - top-level FILES resolve individually in order, each claiming its
|
|
81
|
+
* resolved name, so two same-named files in one batch get successive
|
|
82
|
+
* counters.
|
|
83
|
+
*
|
|
84
|
+
* Only the destination's DIRECT children can be checked — that is all
|
|
85
|
+
* the drop target (one `listAll` level) knows. Deeper paths follow GCS
|
|
86
|
+
* overwrite semantics, which the folder-level rename already shields
|
|
87
|
+
* in practice (a colliding folder is renamed wholesale).
|
|
88
|
+
*
|
|
89
|
+
* Returns resolved paths in input order.
|
|
90
|
+
*/
|
|
91
|
+
export function planBatchNames(relativePaths, taken) {
|
|
92
|
+
const claimed = new Set(taken);
|
|
93
|
+
// One resolution per dropped folder root, shared across its files.
|
|
94
|
+
const folderRenames = new Map();
|
|
95
|
+
return relativePaths.map((path) => {
|
|
96
|
+
const slash = path.indexOf('/');
|
|
97
|
+
if (slash === -1) {
|
|
98
|
+
// Top-level file: resolve individually, claim the result.
|
|
99
|
+
const resolved = resolveCollision(path, claimed);
|
|
100
|
+
claimed.add(resolved);
|
|
101
|
+
return resolved;
|
|
102
|
+
}
|
|
103
|
+
const root = path.slice(0, slash);
|
|
104
|
+
let renamed = folderRenames.get(root);
|
|
105
|
+
if (renamed === undefined) {
|
|
106
|
+
renamed = resolveCollision(root, claimed);
|
|
107
|
+
claimed.add(renamed);
|
|
108
|
+
folderRenames.set(root, renamed);
|
|
109
|
+
}
|
|
110
|
+
return `${renamed}${path.slice(slash)}`;
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=collisionRename.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collisionRename.js","sourceRoot":"","sources":["../../src/storage/collisionRename.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { FirebaseStorage } from 'pyric/storage';
|
|
3
|
+
import type { StorageSelectionEntry } from '../hooks/useStorageSelection.js';
|
|
4
|
+
import type { UseStorageRulesGateResult } from '../hooks/useStorageRulesGate.js';
|
|
5
|
+
import { type StorageDeleteOutcome, type StorageRecursiveDeleteImpl, type UseStorageDeleteOptions } from '../hooks/useStorageDelete.js';
|
|
6
|
+
export interface DeleteSelectionWithConfirmProps {
|
|
7
|
+
/** The package's single Storage handle prop. */
|
|
8
|
+
storage: FirebaseStorage | null | undefined;
|
|
9
|
+
/** What to delete — `useStorageSelection().selected` (or any
|
|
10
|
+
* `{kind, fullPath}` rows). Folders delete recursively. */
|
|
11
|
+
entries: StorageSelectionEntry[];
|
|
12
|
+
/** Folder-walk impl override (default: the `listAll`-driven one). */
|
|
13
|
+
impl?: StorageRecursiveDeleteImpl;
|
|
14
|
+
/** Optimistic seam from `useStorageList`. */
|
|
15
|
+
list?: UseStorageDeleteOptions['list'];
|
|
16
|
+
/**
|
|
17
|
+
* Rules-aware affordance — pass `useStorageRulesGate(storage)`.
|
|
18
|
+
* When ANY selected entry's DELETE verdict denies, the trigger
|
|
19
|
+
* disables with the reason (default trigger: `data-pyric-denied` +
|
|
20
|
+
* `data-pyric-denied-reason` + `title`; `renderTrigger` receives
|
|
21
|
+
* `deniedReason`). For folder entries the verdict evaluates the
|
|
22
|
+
* folder path itself — an approximation of the recursive walk
|
|
23
|
+
* (descendants matched by `{allPaths=**}` rules share the verdict).
|
|
24
|
+
*/
|
|
25
|
+
gate?: Pick<UseStorageRulesGateResult, 'verdictFor'>;
|
|
26
|
+
/** Confirm-dialog title. Default derives from the entry count. */
|
|
27
|
+
title?: string;
|
|
28
|
+
/** Confirm-dialog body. Default lists the selected paths. */
|
|
29
|
+
body?: ReactNode;
|
|
30
|
+
confirmLabel?: string;
|
|
31
|
+
/** Fired after a run with NO failures (e.g. clear the selection +
|
|
32
|
+
* refresh the list). */
|
|
33
|
+
onDeleted?: (outcome: StorageDeleteOutcome) => void;
|
|
34
|
+
/** Fired after a run with failures (the toast already showed). */
|
|
35
|
+
onFailed?: (outcome: StorageDeleteOutcome) => void;
|
|
36
|
+
/** Render override for the trigger button. */
|
|
37
|
+
renderTrigger?: (props: {
|
|
38
|
+
onClick: () => void;
|
|
39
|
+
isRunning: boolean;
|
|
40
|
+
progress: number;
|
|
41
|
+
disabled: boolean;
|
|
42
|
+
/** Set when the rules gate denied the selection (see `gate`). */
|
|
43
|
+
deniedReason?: string;
|
|
44
|
+
}) => ReactNode;
|
|
45
|
+
/** Class forwarded to the default trigger button. */
|
|
46
|
+
className?: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Bulk delete behind the confirm-dialog primitive, with toasts on
|
|
50
|
+
* outcome — wires `useConfirm` + `useStorageDelete` + `useToast` the
|
|
51
|
+
* way `<DeleteWithConfirm>` wires the Firestore trio. Requires
|
|
52
|
+
* `<ConfirmProvider>` AND `<ToastProvider>` ancestors.
|
|
53
|
+
*
|
|
54
|
+
* Outcome toasts: all-success → one `success` toast with the count;
|
|
55
|
+
* any failure → an `error` toast listing each failed path with its
|
|
56
|
+
* typed `StorageError.code`.
|
|
57
|
+
*
|
|
58
|
+
* The default trigger styles via `[data-pyric-ui="delete-selection"]`
|
|
59
|
+
* (+ `[data-pyric-destructive]`, `[data-pyric-running]`,
|
|
60
|
+
* `[data-pyric-denied]` with the reason on
|
|
61
|
+
* `data-pyric-denied-reason`/`title`); it disables while running,
|
|
62
|
+
* when `entries` is empty, or when the rules `gate` denies the
|
|
63
|
+
* selection.
|
|
64
|
+
*/
|
|
65
|
+
export declare function DeleteSelectionWithConfirm({ storage, entries, impl, list, gate, title, body, confirmLabel, onDeleted, onFailed, renderTrigger, className, }: DeleteSelectionWithConfirmProps): import("react").JSX.Element;
|
|
66
|
+
//# sourceMappingURL=DeleteSelectionWithConfirm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DeleteSelectionWithConfirm.d.ts","sourceRoot":"","sources":["../../../src/storage/components/DeleteSelectionWithConfirm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGrD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAC7E,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AACjF,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,uBAAuB,EAC7B,MAAM,8BAA8B,CAAC;AAEtC,MAAM,WAAW,+BAA+B;IAC9C,gDAAgD;IAChD,OAAO,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,CAAC;IAC5C;gEAC4D;IAC5D,OAAO,EAAE,qBAAqB,EAAE,CAAC;IACjC,qEAAqE;IACrE,IAAI,CAAC,EAAE,0BAA0B,CAAC;IAClC,6CAA6C;IAC7C,IAAI,CAAC,EAAE,uBAAuB,CAAC,MAAM,CAAC,CAAC;IACvC;;;;;;;;OAQG;IACH,IAAI,CAAC,EAAE,IAAI,CAAC,yBAAyB,EAAE,YAAY,CAAC,CAAC;IACrD,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;6BACyB;IACzB,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAC;IACpD,kEAAkE;IAClE,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAC;IACnD,8CAA8C;IAC9C,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE;QACtB,OAAO,EAAE,MAAM,IAAI,CAAC;QACpB,SAAS,EAAE,OAAO,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,OAAO,CAAC;QAClB,iEAAiE;QACjE,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,KAAK,SAAS,CAAC;IAChB,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,0BAA0B,CAAC,EACzC,OAAO,EACP,OAAO,EACP,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,IAAI,EACJ,YAAuB,EACvB,SAAS,EACT,QAAQ,EACR,aAAa,EACb,SAAS,GACV,EAAE,+BAA+B,+BA0GjC"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useConfirm } from '../../primitives/useConfirm.js';
|
|
3
|
+
import { useToast } from '../../primitives/Toast.js';
|
|
4
|
+
import { useStorageDelete, } from '../hooks/useStorageDelete.js';
|
|
5
|
+
/**
|
|
6
|
+
* Bulk delete behind the confirm-dialog primitive, with toasts on
|
|
7
|
+
* outcome — wires `useConfirm` + `useStorageDelete` + `useToast` the
|
|
8
|
+
* way `<DeleteWithConfirm>` wires the Firestore trio. Requires
|
|
9
|
+
* `<ConfirmProvider>` AND `<ToastProvider>` ancestors.
|
|
10
|
+
*
|
|
11
|
+
* Outcome toasts: all-success → one `success` toast with the count;
|
|
12
|
+
* any failure → an `error` toast listing each failed path with its
|
|
13
|
+
* typed `StorageError.code`.
|
|
14
|
+
*
|
|
15
|
+
* The default trigger styles via `[data-pyric-ui="delete-selection"]`
|
|
16
|
+
* (+ `[data-pyric-destructive]`, `[data-pyric-running]`,
|
|
17
|
+
* `[data-pyric-denied]` with the reason on
|
|
18
|
+
* `data-pyric-denied-reason`/`title`); it disables while running,
|
|
19
|
+
* when `entries` is empty, or when the rules `gate` denies the
|
|
20
|
+
* selection.
|
|
21
|
+
*/
|
|
22
|
+
export function DeleteSelectionWithConfirm({ storage, entries, impl, list, gate, title, body, confirmLabel = 'Delete', onDeleted, onFailed, renderTrigger, className, }) {
|
|
23
|
+
const confirm = useConfirm();
|
|
24
|
+
const { toast } = useToast();
|
|
25
|
+
const { deleteEntries, isRunning, progress } = useStorageDelete(storage, {
|
|
26
|
+
impl,
|
|
27
|
+
list,
|
|
28
|
+
});
|
|
29
|
+
// Pre-flight DELETE verdicts over the selection (advisory — the
|
|
30
|
+
// enforcement layer still decides; see the `gate` prop).
|
|
31
|
+
const denied = gate
|
|
32
|
+
? entries
|
|
33
|
+
.map((e) => ({ entry: e, verdict: gate.verdictFor(e.fullPath) }))
|
|
34
|
+
.filter((d) => !d.verdict.delete)
|
|
35
|
+
: [];
|
|
36
|
+
const deniedReason = denied.length === 0
|
|
37
|
+
? undefined
|
|
38
|
+
: `Delete denied for ${denied[0].entry.fullPath}${denied.length > 1 ? ` (+${denied.length - 1} more)` : ''}: ${denied[0].verdict.reasons.write.join('; ')}`;
|
|
39
|
+
const disabled = isRunning || entries.length === 0 || storage == null || denied.length > 0;
|
|
40
|
+
const handleClick = async () => {
|
|
41
|
+
if (disabled)
|
|
42
|
+
return;
|
|
43
|
+
const ok = await confirm({
|
|
44
|
+
title: title ??
|
|
45
|
+
(entries.length === 1
|
|
46
|
+
? `Delete ${entries[0].fullPath}?`
|
|
47
|
+
: `Delete ${entries.length} items?`),
|
|
48
|
+
body: body ?? (_jsx("ul", { "data-pyric-delete-selection-paths": true, children: entries.map((e) => (_jsxs("li", { "data-pyric-entry-kind": e.kind, children: [e.fullPath, e.kind === 'folder' ? '/' : ''] }, e.fullPath))) })),
|
|
49
|
+
destructive: true,
|
|
50
|
+
confirmLabel,
|
|
51
|
+
});
|
|
52
|
+
if (!ok)
|
|
53
|
+
return;
|
|
54
|
+
const outcome = await deleteEntries(entries);
|
|
55
|
+
if (outcome.failed.length === 0) {
|
|
56
|
+
toast({
|
|
57
|
+
title: `Deleted ${outcome.deleted.length} ${outcome.deleted.length === 1 ? 'item' : 'items'}`,
|
|
58
|
+
kind: 'success',
|
|
59
|
+
});
|
|
60
|
+
onDeleted?.(outcome);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
toast({
|
|
64
|
+
title: `Delete failed for ${outcome.failed.length} of ${entries.length}`,
|
|
65
|
+
kind: 'error',
|
|
66
|
+
body: (_jsx("ul", { "data-pyric-delete-selection-failures": true, children: outcome.failed.map((f) => (_jsxs("li", { children: [f.fullPath, ":", ' ', f.error.code ?? f.error.message] }, f.fullPath))) })),
|
|
67
|
+
});
|
|
68
|
+
onFailed?.(outcome);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
if (renderTrigger) {
|
|
72
|
+
return (_jsx(_Fragment, { children: renderTrigger({
|
|
73
|
+
onClick: handleClick,
|
|
74
|
+
isRunning,
|
|
75
|
+
progress,
|
|
76
|
+
disabled,
|
|
77
|
+
deniedReason,
|
|
78
|
+
}) }));
|
|
79
|
+
}
|
|
80
|
+
return (_jsx("button", { type: "button", onClick: handleClick, className: className, disabled: disabled, title: deniedReason, "data-pyric-ui": "delete-selection", "data-pyric-destructive": "", "data-pyric-running": isRunning ? '' : undefined, "data-pyric-denied": deniedReason ? '' : undefined, "data-pyric-denied-reason": deniedReason, children: isRunning ? `Deleting… (${progress})` : confirmLabel }));
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=DeleteSelectionWithConfirm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DeleteSelectionWithConfirm.js","sourceRoot":"","sources":["../../../src/storage/components/DeleteSelectionWithConfirm.tsx"],"names":[],"mappings":"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"}
|