@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,58 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { denialReason, markRuleLines, decidingEvaluation, formatValue, traceDepth, } from './format.js';
|
|
3
|
+
import { scopeVars } from './scope.js';
|
|
4
|
+
function lensUid(denial) {
|
|
5
|
+
const lens = denial.lens;
|
|
6
|
+
if (lens && typeof lens === 'object' && 'as' in lens)
|
|
7
|
+
return lens.as;
|
|
8
|
+
return denial.auth?.uid;
|
|
9
|
+
}
|
|
10
|
+
/** Render one scope value, underlining the keys the rule read. */
|
|
11
|
+
function ScopeValue({ value, hits }) {
|
|
12
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
|
|
13
|
+
return _jsx(_Fragment, { children: formatValue(value) });
|
|
14
|
+
}
|
|
15
|
+
const entries = Object.entries(value);
|
|
16
|
+
const hitSet = new Set(hits);
|
|
17
|
+
return (_jsxs(_Fragment, { children: ['{ ', entries.map(([k, v], i) => (_jsxs("span", { children: [i > 0 ? ', ' : '', k, ":", ' ', hitSet.has(k) ? (_jsx("span", { "data-pyric-scope-hit": "", children: formatValue(v) })) : (formatValue(v))] }, k))), ' }'] }));
|
|
18
|
+
}
|
|
19
|
+
/** The step-through evaluation: each sub-expression and its real value. */
|
|
20
|
+
function EvaluationTrace({ trace }) {
|
|
21
|
+
return (_jsx("div", { "data-pyric-trace": "", children: trace.map((node, i) => {
|
|
22
|
+
const depth = traceDepth(trace, i);
|
|
23
|
+
const isFalse = node.value === false;
|
|
24
|
+
return (_jsxs("div", { "data-pyric-trace-node": "", "data-pyric-depth": depth, ...(node.skipped ? { 'data-pyric-skipped': '' } : {}), ...(node.letBinding ? { 'data-pyric-let': node.letBinding.name } : {}), ...(node.inlinedFrom ? { 'data-pyric-frame': node.inlinedFrom.name } : {}), children: [_jsx("span", { "data-pyric-trace-source": "", children: node.source }), _jsx("span", { "data-pyric-trace-value": "", ...(isFalse ? { 'data-pyric-false': '' } : {}), children: node.skipped
|
|
25
|
+
? 'skipped'
|
|
26
|
+
: node.error != null
|
|
27
|
+
? `error: ${node.error}`
|
|
28
|
+
: formatValue(node.value) })] }, i));
|
|
29
|
+
}) }));
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Headless inspector for a single denied Firestore request. Renders, per
|
|
33
|
+
* the `denial-inspector-spec`:
|
|
34
|
+
* - the plain-language reason (`data-pyric-denial-reason`)
|
|
35
|
+
* - the rule source, line-marked (`data-pyric-rule-source`, per-line
|
|
36
|
+
* `data-pyric-line-verdict="deny|allow|skip"`)
|
|
37
|
+
* - the expression step-through (`data-pyric-trace` + per-node hooks)
|
|
38
|
+
* - data in scope (`data-pyric-scope`, `-scope-var`, `-scope-hit`)
|
|
39
|
+
* - the re-run / verify loop (`data-pyric-rerun`)
|
|
40
|
+
* - the cluster of sibling denials (`data-pyric-denial-cluster`)
|
|
41
|
+
* - path resolution for no-match denials (`data-pyric-path-resolution`)
|
|
42
|
+
*
|
|
43
|
+
* Zero styling — every visual decision is a consumer's via the
|
|
44
|
+
* `data-pyric-*` hooks. `mocks/c-debug.html` is the CSS spec.
|
|
45
|
+
*/
|
|
46
|
+
export function DenialInspector({ denial, cluster, onRerunAs, onTestEditedRule, onSelectCluster, className, }) {
|
|
47
|
+
const deciding = decidingEvaluation(denial.evaluation);
|
|
48
|
+
const lines = markRuleLines(denial.rulesSource, denial.evaluation, denial.method);
|
|
49
|
+
const scope = scopeVars(denial);
|
|
50
|
+
const rerunUid = lensUid(denial);
|
|
51
|
+
const isNoMatch = denial.evaluation.length === 0;
|
|
52
|
+
return (_jsxs("div", { className: className, "data-pyric-ui": "denial-inspector", children: [_jsxs("header", { "data-pyric-denial-header": "", children: [_jsxs("p", { "data-pyric-denial-title": "", children: ["Denied: ", _jsx("span", { "data-pyric-denial-method": "", children: denial.method }), ' ', _jsx("span", { "data-pyric-denial-path": "", children: denial.path })] }), _jsxs("p", { "data-pyric-denial-context": "", children: [denial.auth ? `by ${denial.auth.uid}` : 'unauthenticated', denial.lens && typeof denial.lens === 'object' && 'as' in denial.lens
|
|
53
|
+
? ` · acting as ${denial.lens.as}`
|
|
54
|
+
: denial.lens === 'admin'
|
|
55
|
+
? ' · admin'
|
|
56
|
+
: ''] })] }), _jsx("p", { "data-pyric-denial-reason": "", children: denialReason(denial.evaluation, denial.method, denial.path) }), _jsx("section", { "data-pyric-rule-source": "", children: lines.map((line) => (_jsxs("div", { "data-pyric-rule-line": "", "data-pyric-line-number": line.number, ...(line.verdict ? { 'data-pyric-line-verdict': line.verdict } : {}), children: [_jsx("span", { "data-pyric-line-gutter": "", children: line.number }), _jsx("span", { "data-pyric-line-text": "", children: line.text }), line.note ? _jsx("span", { "data-pyric-line-note": "", children: line.note }) : null, line.verdict === 'deny' ? (_jsx("span", { "data-pyric-line-badge": "", children: "denied" })) : null] }, line.number))) }), deciding?.expressionTrace && deciding.expressionTrace.length > 0 ? (_jsx(EvaluationTrace, { trace: deciding.expressionTrace })) : null, scope.length > 0 ? (_jsx("section", { "data-pyric-scope": "", children: scope.map((v) => (_jsxs("div", { "data-pyric-scope-var": v.name, children: [_jsx("span", { "data-pyric-scope-name": "", children: v.name }), _jsx("span", { "data-pyric-scope-tag": "", children: v.tag }), _jsx("span", { "data-pyric-scope-value": "", children: _jsx(ScopeValue, { value: v.value, hits: v.hits }) })] }, v.name))) })) : null, isNoMatch && denial.pathResolution ? (_jsx("section", { "data-pyric-path-resolution": "", children: denial.pathResolution.attempts.map((attempt, i) => (_jsxs("div", { "data-pyric-path-attempt": "", "data-pyric-matched-segments": `${attempt.matchedSegments}/${attempt.totalSegments}`, ...(attempt.matched ? { 'data-pyric-matched': '' } : {}), ...(attempt.reason ? { 'data-pyric-reason': attempt.reason } : {}), children: [_jsx("span", { "data-pyric-attempt-path": "", children: attempt.blockPath }), attempt.reason ? (_jsx("span", { "data-pyric-attempt-reason": "", children: attempt.reason })) : null] }, i))) })) : null, onRerunAs || onTestEditedRule ? (_jsxs("section", { "data-pyric-rerun": "", children: [onRerunAs && rerunUid ? (_jsxs("button", { type: "button", "data-pyric-rerun-as": "", "data-pyric-rerun-uid": rerunUid, onClick: () => onRerunAs(rerunUid), children: ["Re-run as ", rerunUid] })) : null, onTestEditedRule ? (_jsx("button", { type: "button", "data-pyric-test-edited-rule": "", onClick: () => onTestEditedRule(), children: "Test against an edited rule" })) : null] })) : null, cluster && cluster.length > 0 ? (_jsx("section", { "data-pyric-denial-cluster": "", children: cluster.map((sibling, i) => (_jsx("button", { type: "button", "data-pyric-cluster-item": "", onClick: () => onSelectCluster?.(sibling), children: _jsx("span", { "data-pyric-cluster-path": "", children: sibling.path }) }, i))) })) : null] }));
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=DenialInspector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DenialInspector.js","sourceRoot":"","sources":["../../../src/rules/components/DenialInspector.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { RuleEvaluation, ExprTraceEntry, LineVerdict, FirestoreMethod } from '../types.js';
|
|
2
|
+
/** Operations a request method satisfies — `update` matches `update` and
|
|
3
|
+
* `write`, etc. Mirrors the simulator's `methodToOperations`. */
|
|
4
|
+
export declare function methodOperations(method: FirestoreMethod): string[];
|
|
5
|
+
/**
|
|
6
|
+
* The allow rule that decided the denial: the last rule actually
|
|
7
|
+
* evaluated (DENY/ERROR). Under OR semantics the simulator stops at the
|
|
8
|
+
* first ALLOW; on a denial no rule allowed, so the deciding rule is the
|
|
9
|
+
* last evaluated one — the closest miss the user should reason about.
|
|
10
|
+
*/
|
|
11
|
+
export declare function decidingEvaluation(evaluation: RuleEvaluation[]): RuleEvaluation | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* A plain-language reason for the denial, derived from the deciding
|
|
14
|
+
* `RuleEvaluation`. Falls back to a no-match explanation when no allow
|
|
15
|
+
* rule was evaluated.
|
|
16
|
+
*/
|
|
17
|
+
export declare function denialReason(evaluation: RuleEvaluation[], method: FirestoreMethod, path: string): string;
|
|
18
|
+
export interface RuleLine {
|
|
19
|
+
number: number;
|
|
20
|
+
text: string;
|
|
21
|
+
verdict?: LineVerdict;
|
|
22
|
+
/** A short note for skipped lines, e.g. "not checked, this is an update". */
|
|
23
|
+
note?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Split the rules source into numbered lines and mark each `allow` line
|
|
27
|
+
* with a verdict per the spec:
|
|
28
|
+
* - the deciding rule's line → `deny`
|
|
29
|
+
* - an allow line whose operations don't include the method → `skip`
|
|
30
|
+
* - any other allow line → `allow`
|
|
31
|
+
*
|
|
32
|
+
* Verdicts are matched to source lines via `RuleEvaluation.line` (1-indexed
|
|
33
|
+
* `allow` keyword). Lines without a matching evaluation entry get no verdict.
|
|
34
|
+
*/
|
|
35
|
+
export declare function markRuleLines(rulesSource: string, evaluation: RuleEvaluation[], method: FirestoreMethod): RuleLine[];
|
|
36
|
+
/** Render a trace value the way the mock shows it: JSON-ish, quoted
|
|
37
|
+
* strings, `false`/`true`/`null` bare. */
|
|
38
|
+
export declare function formatValue(value: unknown): string;
|
|
39
|
+
/** Depth of a trace node from its `parent` chain (0 for roots). */
|
|
40
|
+
export declare function traceDepth(entries: ExprTraceEntry[], index: number): number;
|
|
41
|
+
/**
|
|
42
|
+
* The set of scope variable roots whose deciding values appear in the
|
|
43
|
+
* trace — `request.auth`, `request.resource.data`, `resource.data`.
|
|
44
|
+
* Used to underline the values the rule actually read.
|
|
45
|
+
*/
|
|
46
|
+
export interface ScopeVar {
|
|
47
|
+
/** The dotted path, e.g. `request.auth`. */
|
|
48
|
+
name: string;
|
|
49
|
+
/** A short human tag, e.g. "who made the request". */
|
|
50
|
+
tag: string;
|
|
51
|
+
/** The value to render. */
|
|
52
|
+
value: unknown;
|
|
53
|
+
/** Leaf keys whose values the rule read (for the `hit` underline). */
|
|
54
|
+
hits: string[];
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/rules/components/format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGhG;kEACkE;AAClE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,EAAE,CASlE;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,cAAc,EAAE,GAAG,cAAc,GAAG,SAAS,CAM3F;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,cAAc,EAAE,EAC5B,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,MAAM,GACX,MAAM,CAuBR;AAED,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,6EAA6E;IAC7E,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,cAAc,EAAE,EAC5B,MAAM,EAAE,eAAe,GACtB,QAAQ,EAAE,CAsCZ;AAED;2CAC2C;AAC3C,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAYlD;AAED,mEAAmE;AACnE,wBAAgB,UAAU,CAAC,OAAO,EAAE,cAAc,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAW3E;AAED;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACvB,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,GAAG,EAAE,MAAM,CAAC;IACZ,2BAA2B;IAC3B,KAAK,EAAE,OAAO,CAAC;IACf,sEAAsE;IACtE,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { truncateVectorsForDisplay } from '../../firestore/index.js';
|
|
2
|
+
/** Operations a request method satisfies — `update` matches `update` and
|
|
3
|
+
* `write`, etc. Mirrors the simulator's `methodToOperations`. */
|
|
4
|
+
export function methodOperations(method) {
|
|
5
|
+
switch (method) {
|
|
6
|
+
case 'get': return ['get', 'read'];
|
|
7
|
+
case 'list': return ['list', 'read'];
|
|
8
|
+
case 'create': return ['create', 'write'];
|
|
9
|
+
case 'update': return ['update', 'write'];
|
|
10
|
+
case 'delete': return ['delete', 'write'];
|
|
11
|
+
default: return [method];
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* The allow rule that decided the denial: the last rule actually
|
|
16
|
+
* evaluated (DENY/ERROR). Under OR semantics the simulator stops at the
|
|
17
|
+
* first ALLOW; on a denial no rule allowed, so the deciding rule is the
|
|
18
|
+
* last evaluated one — the closest miss the user should reason about.
|
|
19
|
+
*/
|
|
20
|
+
export function decidingEvaluation(evaluation) {
|
|
21
|
+
if (evaluation.length === 0)
|
|
22
|
+
return undefined;
|
|
23
|
+
// Prefer the last non-skipped (i.e. actually-evaluated) entry. Every
|
|
24
|
+
// entry in `evaluation` was matched by method, so they're all
|
|
25
|
+
// evaluated; the last is the deciding one.
|
|
26
|
+
return evaluation[evaluation.length - 1];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* A plain-language reason for the denial, derived from the deciding
|
|
30
|
+
* `RuleEvaluation`. Falls back to a no-match explanation when no allow
|
|
31
|
+
* rule was evaluated.
|
|
32
|
+
*/
|
|
33
|
+
export function denialReason(evaluation, method, path) {
|
|
34
|
+
const deciding = decidingEvaluation(evaluation);
|
|
35
|
+
if (!deciding) {
|
|
36
|
+
return `No security rule matched ${method} ${path}, so the request was denied by default.`;
|
|
37
|
+
}
|
|
38
|
+
if (deciding.verdict === 'UNSUPPORTED') {
|
|
39
|
+
return (`The simulator couldn't evaluate the ${deciding.operations.join('/')} rule` +
|
|
40
|
+
(deciding.message ? ` (${deciding.message})` : '') +
|
|
41
|
+
' — this is a gap in the local simulator, not necessarily your rule.');
|
|
42
|
+
}
|
|
43
|
+
if (deciding.verdict === 'ERROR') {
|
|
44
|
+
return (`The ${deciding.operations.join('/')} rule threw while evaluating` +
|
|
45
|
+
(deciding.message ? `: ${deciding.message}` : '') +
|
|
46
|
+
', which denies the request.');
|
|
47
|
+
}
|
|
48
|
+
const cond = deciding.conditionText
|
|
49
|
+
? `The ${deciding.operations.join('/')} rule requires ${deciding.conditionText}, which evaluated to false`
|
|
50
|
+
: `The ${deciding.operations.join('/')} rule's condition evaluated to false`;
|
|
51
|
+
return `${cond}, so the request was denied.`;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Split the rules source into numbered lines and mark each `allow` line
|
|
55
|
+
* with a verdict per the spec:
|
|
56
|
+
* - the deciding rule's line → `deny`
|
|
57
|
+
* - an allow line whose operations don't include the method → `skip`
|
|
58
|
+
* - any other allow line → `allow`
|
|
59
|
+
*
|
|
60
|
+
* Verdicts are matched to source lines via `RuleEvaluation.line` (1-indexed
|
|
61
|
+
* `allow` keyword). Lines without a matching evaluation entry get no verdict.
|
|
62
|
+
*/
|
|
63
|
+
export function markRuleLines(rulesSource, evaluation, method) {
|
|
64
|
+
const deciding = decidingEvaluation(evaluation);
|
|
65
|
+
const ops = methodOperations(method);
|
|
66
|
+
// line → verdict, from the evaluated rules.
|
|
67
|
+
const byLine = new Map();
|
|
68
|
+
const noteByLine = new Map();
|
|
69
|
+
for (const e of evaluation) {
|
|
70
|
+
if (e.line == null)
|
|
71
|
+
continue;
|
|
72
|
+
if (e === deciding)
|
|
73
|
+
byLine.set(e.line, 'deny');
|
|
74
|
+
else
|
|
75
|
+
byLine.set(e.line, 'allow');
|
|
76
|
+
}
|
|
77
|
+
// Detect skipped allow lines by scanning the source for `allow <ops>:`
|
|
78
|
+
// declarations whose operations don't intersect the request method.
|
|
79
|
+
const rawLines = rulesSource.split('\n');
|
|
80
|
+
const allowRe = /^\s*allow\s+([a-z,\s]+?)\s*:/;
|
|
81
|
+
return rawLines.map((text, i) => {
|
|
82
|
+
const number = i + 1;
|
|
83
|
+
const line = { number, text };
|
|
84
|
+
const fromEval = byLine.get(number);
|
|
85
|
+
if (fromEval) {
|
|
86
|
+
line.verdict = fromEval;
|
|
87
|
+
return line;
|
|
88
|
+
}
|
|
89
|
+
const m = allowRe.exec(text);
|
|
90
|
+
if (m) {
|
|
91
|
+
const declared = m[1].split(',').map(s => s.trim()).filter(Boolean);
|
|
92
|
+
const matches = declared.some(op => ops.includes(op));
|
|
93
|
+
if (!matches) {
|
|
94
|
+
line.verdict = 'skip';
|
|
95
|
+
line.note = `not checked, this is a ${method}`;
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
// Declared for this method but not in the evaluation trace
|
|
99
|
+
// (e.g. a different match block). Treat as a normal allow line.
|
|
100
|
+
line.verdict = 'allow';
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return line;
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
/** Render a trace value the way the mock shows it: JSON-ish, quoted
|
|
107
|
+
* strings, `false`/`true`/`null` bare. */
|
|
108
|
+
export function formatValue(value) {
|
|
109
|
+
if (value === undefined)
|
|
110
|
+
return '∅';
|
|
111
|
+
if (typeof value === 'string')
|
|
112
|
+
return JSON.stringify(value);
|
|
113
|
+
if (value === null || typeof value === 'boolean' || typeof value === 'number') {
|
|
114
|
+
return String(value);
|
|
115
|
+
}
|
|
116
|
+
try {
|
|
117
|
+
// Truncate vectors so a real embedding never dumps its full array into a trace.
|
|
118
|
+
return JSON.stringify(truncateVectorsForDisplay(value));
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
return String(value);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/** Depth of a trace node from its `parent` chain (0 for roots). */
|
|
125
|
+
export function traceDepth(entries, index) {
|
|
126
|
+
let depth = 0;
|
|
127
|
+
let cur = entries[index]?.parent ?? null;
|
|
128
|
+
// Guard against malformed chains.
|
|
129
|
+
let guard = 0;
|
|
130
|
+
while (cur != null && guard < entries.length + 1) {
|
|
131
|
+
depth++;
|
|
132
|
+
cur = entries[cur]?.parent ?? null;
|
|
133
|
+
guard++;
|
|
134
|
+
}
|
|
135
|
+
return depth;
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../../src/rules/components/format.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { DenialInspector } from './DenialInspector.js';
|
|
2
|
+
export { denialReason, markRuleLines, decidingEvaluation, methodOperations, formatValue, traceDepth, type RuleLine, type ScopeVar, } from './format.js';
|
|
3
|
+
export { scopeVars } from './scope.js';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/rules/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EACL,YAAY,EACZ,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,KAAK,QAAQ,EACb,KAAK,QAAQ,GACd,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/rules/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EACL,YAAY,EACZ,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,WAAW,EACX,UAAU,GAGX,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Denial } from '../types.js';
|
|
2
|
+
import { type ScopeVar } from './format.js';
|
|
3
|
+
/**
|
|
4
|
+
* Build the "data in scope" rows for a denial: `request.auth`,
|
|
5
|
+
* `request.resource.data`, and `resource.data` — each present only when
|
|
6
|
+
* the denial carries that payload. `hits` marks the leaf keys the
|
|
7
|
+
* deciding rule actually read.
|
|
8
|
+
*/
|
|
9
|
+
export declare function scopeVars(denial: Denial): ScopeVar[];
|
|
10
|
+
//# sourceMappingURL=scope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../../src/rules/components/scope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAkB,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAsB,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAqChE;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,EAAE,CA8BpD"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { decidingEvaluation } from './format.js';
|
|
2
|
+
/**
|
|
3
|
+
* Leaf keys the rule read off each scope root, discovered from the
|
|
4
|
+
* deciding rule's expression trace. We scan every trace node's `source`
|
|
5
|
+
* for accessors rooted at one of the three scope roots and record the
|
|
6
|
+
* first segment after the root (e.g. `request.auth.uid` → root
|
|
7
|
+
* `request.auth`, hit `uid`). These drive the `data-pyric-scope-hit`
|
|
8
|
+
* underline so the user sees exactly which fields the rule compared.
|
|
9
|
+
*/
|
|
10
|
+
const SCOPE_ROOTS = [
|
|
11
|
+
{ root: 'request.resource.data', key: 'requestData' },
|
|
12
|
+
{ root: 'resource.data', key: 'resourceData' },
|
|
13
|
+
{ root: 'request.auth', key: 'auth' },
|
|
14
|
+
];
|
|
15
|
+
function collectHits(entries) {
|
|
16
|
+
const hits = new Map();
|
|
17
|
+
for (const entry of entries) {
|
|
18
|
+
const src = entry.source;
|
|
19
|
+
// Longest root first so `request.resource.data` wins over a bare
|
|
20
|
+
// `request` prefix.
|
|
21
|
+
for (const { root } of SCOPE_ROOTS) {
|
|
22
|
+
if (src === root || src.startsWith(root + '.')) {
|
|
23
|
+
const rest = src.slice(root.length).replace(/^\./, '');
|
|
24
|
+
const leaf = rest.split(/[.[]/)[0];
|
|
25
|
+
if (leaf) {
|
|
26
|
+
if (!hits.has(root))
|
|
27
|
+
hits.set(root, new Set());
|
|
28
|
+
hits.get(root).add(leaf);
|
|
29
|
+
}
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return hits;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Build the "data in scope" rows for a denial: `request.auth`,
|
|
38
|
+
* `request.resource.data`, and `resource.data` — each present only when
|
|
39
|
+
* the denial carries that payload. `hits` marks the leaf keys the
|
|
40
|
+
* deciding rule actually read.
|
|
41
|
+
*/
|
|
42
|
+
export function scopeVars(denial) {
|
|
43
|
+
const deciding = decidingEvaluation(denial.evaluation);
|
|
44
|
+
const hits = deciding?.expressionTrace ? collectHits(deciding.expressionTrace) : new Map();
|
|
45
|
+
const rows = [];
|
|
46
|
+
if (denial.auth !== null) {
|
|
47
|
+
rows.push({
|
|
48
|
+
name: 'request.auth',
|
|
49
|
+
tag: 'who made the request',
|
|
50
|
+
value: denial.auth,
|
|
51
|
+
hits: [...(hits.get('request.auth') ?? [])],
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
if (denial.requestData !== undefined) {
|
|
55
|
+
rows.push({
|
|
56
|
+
name: 'request.resource.data',
|
|
57
|
+
tag: 'what was written',
|
|
58
|
+
value: denial.requestData,
|
|
59
|
+
hits: [...(hits.get('request.resource.data') ?? [])],
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
if (denial.resourceData != null) {
|
|
63
|
+
rows.push({
|
|
64
|
+
name: 'resource.data',
|
|
65
|
+
tag: 'the existing document',
|
|
66
|
+
value: denial.resourceData,
|
|
67
|
+
hits: [...(hits.get('resource.data') ?? [])],
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return rows;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=scope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.js","sourceRoot":"","sources":["../../../src/rules/components/scope.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/rules/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,KAAK,aAAa,EAClB,KAAK,WAAW,GACjB,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/rules/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,GAGf,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { type RuleEvaluation, type PathResolutionTrace } from 'pyric/rules';
|
|
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,aAAa,CAAC;AACrB,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';
|
|
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,aAAa,CAAC;AAkCrB,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"}
|