@jmruthers/pace-core 0.6.10 → 0.6.11
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/CHANGELOG.md +21 -0
- package/audit-tool/00-dependencies.cjs +46 -13
- package/audit-tool/audits/01-pace-core-compliance.cjs +96 -21
- package/audit-tool/audits/02-project-structure.cjs +13 -3
- package/audit-tool/audits/03-architecture.cjs +78 -4
- package/audit-tool/audits/04-code-quality.cjs +9 -2
- package/audit-tool/audits/05-styling.cjs +19 -7
- package/audit-tool/audits/06-security-rbac.cjs +105 -14
- package/audit-tool/audits/07-api-tech-stack.cjs +31 -15
- package/audit-tool/audits/08-testing-documentation.cjs +11 -3
- package/audit-tool/audits/09-operations.cjs +19 -7
- package/audit-tool/index.cjs +22 -11
- package/audit-tool/utils/report-utils.cjs +4 -0
- package/cursor-rules/01-pace-core-compliance.mdc +1 -0
- package/cursor-rules/02-project-structure.mdc +1 -0
- package/cursor-rules/03-architecture.mdc +3 -1
- package/cursor-rules/04-code-quality.mdc +1 -0
- package/cursor-rules/05-styling.mdc +41 -7
- package/cursor-rules/06-security-rbac.mdc +2 -1
- package/cursor-rules/07-api-tech-stack.mdc +1 -0
- package/cursor-rules/08-testing-documentation.mdc +1 -0
- package/cursor-rules/09-operations.mdc +1 -0
- package/dist/{DataTable-SAXFG4XI.js → DataTable-EFYP2QLE.js} +10 -7
- package/dist/{InactivityServiceProvider-DHryoh6K.d.ts → InactivityServiceProvider-BbxwwDz1.d.ts} +10 -1
- package/dist/{UnifiedAuthProvider-CiBAl9-s.d.ts → UnifiedAuthProvider-Bkt_tzdS.d.ts} +56 -24
- package/dist/{api-F47QJ7FX.js → api-BZR2CYXL.js} +3 -2
- package/dist/api-result-USV1Czr-.d.ts +51 -0
- package/dist/{audit-Z6ZZBWLU.js → audit-HI2DHUVU.js} +2 -1
- package/dist/{auth-BZOJqrdd.d.ts → auth-JvdRVaud.d.ts} +1 -1
- package/dist/{chunk-KSNLMI7N.js → chunk-2DL2WSOE.js} +1 -155
- package/dist/{chunk-MPY44PWB.js → chunk-2OEVOGGR.js} +4648 -3560
- package/dist/chunk-44CNXN4P.js +15 -0
- package/dist/{chunk-Y4PF6HIM.js → chunk-4R3T5ENU.js} +867 -786
- package/dist/{chunk-LNHFAF4X.js → chunk-7A6IMHH2.js} +289 -247
- package/dist/chunk-CU2BU2MQ.js +2 -0
- package/dist/{chunk-JJEYZ3DX.js → chunk-D6BMFMQZ.js} +37 -2
- package/dist/{chunk-BCTXBU6U.js → chunk-ENLXB7GP.js} +88 -71
- package/dist/{chunk-FBZ7U3ID.js → chunk-J2KQK6DG.js} +937 -987
- package/dist/{chunk-TFIPNIPE.js → chunk-KJXRL3XE.js} +3300 -2245
- package/dist/{chunk-3GWSPISD.js → chunk-L5LFKKLJ.js} +1 -1
- package/dist/{chunk-X5EAU5G7.js → chunk-PCSHBLPB.js} +132 -114
- package/dist/{chunk-NIU6DPQV.js → chunk-QRYSEPHB.js} +2 -0
- package/dist/{chunk-KYURMOQM.js → chunk-V7FTM2LU.js} +423 -320
- package/dist/chunk-WY6Y7KC3.js +264 -0
- package/dist/{chunk-FN52B75D.js → chunk-XOJME5T7.js} +176 -15
- package/dist/{chunk-7YDC7LMU.js → chunk-XPFVT3GN.js} +71 -66
- package/dist/{chunk-66R6RLUZ.js → chunk-YFTFFJIV.js} +3 -3
- package/dist/{chunk-W46INAVW.js → chunk-YYTWKVHO.js} +688 -570
- package/dist/components.d.ts +8 -7
- package/dist/components.js +17 -15
- package/dist/{database.generated-DT8JTZiP.d.ts → database.generated-qkdoiVrJ.d.ts} +45 -10
- package/dist/eslint-rules/index.cjs +3 -0
- package/dist/eslint-rules/rules/03-architecture.cjs +74 -0
- package/dist/eslint-rules/rules/06-security-rbac.cjs +74 -0
- package/dist/{event-WTAQuGcq.d.ts → event-BfCox3N2.d.ts} +36 -10
- package/dist/{file-reference-BavO2eQj.d.ts → file-reference-DU1hcawx.d.ts} +29 -13
- package/dist/hooks.d.ts +22 -9
- package/dist/hooks.js +34 -25
- package/dist/icons/index.d.ts +1 -0
- package/dist/icons/index.js +1 -0
- package/dist/index.d.ts +66 -177
- package/dist/index.js +316 -340
- package/dist/pagination-BW1mqywp.d.ts +201 -0
- package/dist/providers.d.ts +6 -5
- package/dist/providers.js +5 -3
- package/dist/rbac/index.d.ts +123 -138
- package/dist/rbac/index.js +10 -8
- package/dist/theming/runtime.d.ts +19 -2
- package/dist/theming/runtime.js +1 -1
- package/dist/{timezone-K-ptz3HO.d.ts → timezone-BTWWXKVY.d.ts} +1 -1
- package/dist/types.d.ts +17 -10
- package/dist/types.js +1 -0
- package/dist/{usePublicPageContext-vxBlEHO9.d.ts → usePublicPageContext-B91dGYW1.d.ts} +433 -356
- package/dist/{usePublicRouteParams-G3Ks53mk.d.ts → usePublicRouteParams-BgV6VhMi.d.ts} +73 -4
- package/dist/utils.d.ts +163 -145
- package/dist/utils.js +42 -25
- package/docs/api/modules.md +782 -643
- package/docs/api-reference/rpc-functions.md +12 -3
- package/docs/core-concepts/rbac-system.md +8 -0
- package/docs/getting-started/cursor-rules.md +17 -20
- package/docs/getting-started/dependencies.md +1 -1
- package/docs/getting-started/setup.md +235 -0
- package/docs/implementation-guides/authentication.md +27 -0
- package/docs/implementation-guides/data-tables.md +176 -3
- package/docs/migration/ApiResult-migration.md +25 -0
- package/docs/rbac/api-reference.md +33 -31
- package/docs/standards/0-standards-overview.md +50 -15
- package/docs/standards/1-pace-core-compliance-standards.md +62 -57
- package/docs/standards/2-project-structure-standards.md +33 -16
- package/docs/standards/3-architecture-standards.md +41 -1
- package/docs/standards/4-code-quality-standards.md +26 -6
- package/docs/standards/5-styling-standards.md +35 -1
- package/docs/standards/6-security-rbac-standards.md +66 -0
- package/docs/standards/7-api-tech-stack-standards.md +25 -14
- package/docs/standards/8-testing-documentation-standards.md +31 -0
- package/docs/standards/9-operations-standards.md +19 -0
- package/docs/standards/README.md +20 -201
- package/docs/testing/test-setup-for-consumers.md +2 -0
- package/docs/troubleshooting/common-issues.md +17 -1
- package/docs/troubleshooting/organisation-context-setup.md +8 -0
- package/docs/troubleshooting/print-event-name-css-variable-analysis.md +217 -0
- package/eslint-config-pace-core.cjs +20 -0
- package/package.json +14 -20
- package/scripts/{build-docs-incremental.js → build-docs.js} +3 -2
- package/scripts/setup.cjs +536 -0
- package/scripts/validate.cjs +480 -0
- package/src/__tests__/helpers/{__tests__/component-test-utils.test.tsx → component-test-utils.test.tsx} +3 -3
- package/src/__tests__/helpers/{__tests__/optimized-test-setup.test.ts → optimized-test-setup.test.ts} +2 -2
- package/src/__tests__/helpers/{__tests__/supabaseMock.test.ts → supabaseMock.test.ts} +2 -2
- package/src/__tests__/helpers/{__tests__/test-providers.test.tsx → test-providers.test.tsx} +1 -1
- package/src/__tests__/helpers/test-providers.tsx +37 -39
- package/src/__tests__/helpers/{__tests__/test-utils.test.tsx → test-utils.test.tsx} +4 -3
- package/src/__tests__/helpers/{__tests__/timer-utils.test.ts → timer-utils.test.ts} +2 -2
- package/src/assets/app-icons/index.test.ts +304 -0
- package/src/components/AddressField/AddressField.test.tsx +1 -1
- package/src/components/AddressField/AddressField.tsx +238 -212
- package/src/components/Button/Button.tsx +1 -1
- package/src/components/Card/Card.test.tsx +172 -17
- package/src/components/Card/Card.tsx +19 -10
- package/src/components/ContextSelector/ContextSelector.internals.tsx +204 -0
- package/src/components/ContextSelector/{__tests__/ContextSelector.test.tsx → ContextSelector.test.tsx} +6 -6
- package/src/components/ContextSelector/ContextSelector.tsx +66 -280
- package/src/components/ContextSelector/ContextSelector.types.ts +35 -0
- package/src/components/ContextSelector/useContextSelectorState.tsx +195 -0
- package/src/components/DataTable/AUDIT_REPORT.md +59 -44
- package/src/components/DataTable/{__tests__/DataTable.comprehensive.test.tsx → DataTable.comprehensive.test.tsx} +6 -6
- package/src/components/DataTable/{__tests__/DataTable.default-state.test.tsx → DataTable.default-state.test.tsx} +5 -5
- package/src/components/DataTable/{__tests__/DataTable.export.test.tsx → DataTable.export.test.tsx} +10 -10
- package/src/components/DataTable/{__tests__/DataTable.grouping-aggregation.test.tsx → DataTable.grouping-aggregation.test.tsx} +6 -6
- package/src/components/DataTable/{__tests__/DataTable.hooks.test.tsx → DataTable.hooks.test.tsx} +6 -6
- package/src/components/DataTable/{__tests__/DataTable.select-label-display.test.tsx → DataTable.select-label-display.test.tsx} +6 -6
- package/src/components/DataTable/DataTable.test.tsx +787 -416
- package/src/components/DataTable/DataTable.tsx +12 -12
- package/src/components/DataTable/DataTableCore.integration.test.tsx +458 -0
- package/src/components/DataTable/{__tests__/DataTableCore.test-setup.ts → DataTableCore.test-setup.ts} +10 -9
- package/src/components/DataTable/{__tests__/DataTableCore.test.tsx → DataTableCore.test.tsx} +8 -8
- package/src/components/DataTable/{__tests__/README.md → README.md} +17 -7
- package/src/components/DataTable/TESTING.md +101 -0
- package/src/components/DataTable/{__tests__/a11y.basic.test.tsx → a11y.basic.test.tsx} +34 -34
- package/src/components/DataTable/components/DataTableCore.tsx +104 -864
- package/src/components/DataTable/components/{__tests__/GroupingDropdown.test.tsx → GroupingDropdown.test.tsx} +17 -8
- package/src/components/DataTable/components/GroupingDropdown.tsx +2 -2
- package/src/components/DataTable/components/ImportModal.tsx +61 -559
- package/src/components/DataTable/components/ImportModalFileSection.tsx +148 -0
- package/src/components/DataTable/context/{__tests__/DataTableContext.test.tsx → DataTableContext.test.tsx} +2 -2
- package/src/components/DataTable/context/DataTableContext.tsx +7 -6
- package/src/components/DataTable/core/{__tests__/ColumnFactory.test.ts → ColumnFactory.test.ts} +2 -2
- package/src/components/DataTable/hooks/{__tests__/useColumnOrderPersistence.test.ts → useColumnOrderPersistence.test.ts} +2 -2
- package/src/components/DataTable/hooks/{__tests__/useColumnVisibilityPersistence.test.ts → useColumnVisibilityPersistence.test.ts} +2 -2
- package/src/components/DataTable/hooks/{__tests__/useDataTableConfiguration.test.ts → useDataTableConfiguration.test.ts} +3 -3
- package/src/components/DataTable/hooks/useDataTableConfiguration.ts +14 -2
- package/src/components/DataTable/hooks/{__tests__/useDataTableDataPipeline.test.ts → useDataTableDataPipeline.test.ts} +6 -6
- package/src/components/DataTable/hooks/useDataTableDeletionBatching.test.ts +127 -0
- package/src/components/DataTable/hooks/useDataTableDeletionBatching.ts +106 -0
- package/src/components/DataTable/hooks/useDataTableEffectiveActions.test.ts +461 -0
- package/src/components/DataTable/hooks/useDataTableEffectiveActions.ts +238 -0
- package/src/components/DataTable/hooks/useDataTableLayoutHandlers.test.ts +296 -0
- package/src/components/DataTable/hooks/useDataTableLayoutHandlers.ts +175 -0
- package/src/components/DataTable/hooks/useDataTablePaginationSync.test.ts +203 -0
- package/src/components/DataTable/hooks/useDataTablePaginationSync.ts +109 -0
- package/src/components/DataTable/hooks/{__tests__/useDataTablePermissions.test.ts → useDataTablePermissions.test.ts} +11 -11
- package/src/components/DataTable/hooks/useDataTablePermissions.ts +79 -247
- package/src/components/DataTable/hooks/useDataTablePipeline.test.tsx +219 -0
- package/src/components/DataTable/hooks/useDataTablePipeline.tsx +239 -0
- package/src/components/DataTable/hooks/useDataTableRenderGuard.test.tsx +316 -0
- package/src/components/DataTable/hooks/useDataTableRenderGuard.tsx +195 -0
- package/src/components/DataTable/hooks/useDataTableScope.test.ts +110 -0
- package/src/components/DataTable/hooks/useDataTableScope.ts +123 -0
- package/src/components/DataTable/hooks/{__tests__/useDataTableState.test.ts → useDataTableState.test.ts} +47 -5
- package/src/components/DataTable/hooks/useDataTableState.ts +145 -94
- package/src/components/DataTable/hooks/useDataTableStateAndPersistence.test.ts +277 -0
- package/src/components/DataTable/hooks/useDataTableStateAndPersistence.ts +222 -0
- package/src/components/DataTable/hooks/useDataTableSuperAdmin.test.ts +93 -0
- package/src/components/DataTable/hooks/useDataTableSuperAdmin.ts +86 -0
- package/src/components/DataTable/hooks/useDataTableTableInstance.test.ts +185 -0
- package/src/components/DataTable/hooks/useDataTableTableInstance.ts +178 -0
- package/src/components/DataTable/hooks/{__tests__/useEffectiveColumnOrder.test.ts → useEffectiveColumnOrder.test.ts} +2 -2
- package/src/components/DataTable/hooks/{__tests__/useHierarchicalState.test.ts → useHierarchicalState.test.ts} +2 -2
- package/src/components/DataTable/{components/hooks → hooks}/useImportModalFocus.test.ts +3 -3
- package/src/components/DataTable/{components/hooks → hooks}/useImportModalFocus.ts +2 -2
- package/src/components/DataTable/hooks/useImportModalState.test.ts +390 -0
- package/src/components/DataTable/hooks/useImportModalState.ts +345 -0
- package/src/components/DataTable/hooks/{__tests__/useKeyboardNavigation.test.ts → useKeyboardNavigation.test.ts} +3 -3
- package/src/components/DataTable/hooks/useKeyboardNavigation.ts +309 -269
- package/src/components/DataTable/{components/hooks → hooks}/usePermissionTracking.test.ts +3 -3
- package/src/components/DataTable/{components/hooks → hooks}/usePermissionTracking.ts +3 -3
- package/src/components/DataTable/hooks/{__tests__/useServerSideDataEffect.test.ts → useServerSideDataEffect.test.ts} +2 -2
- package/src/components/DataTable/hooks/useServerSideDataEffect.ts +14 -3
- package/src/components/DataTable/hooks/{__tests__/useTableColumns.test.ts → useTableColumns.test.ts} +2 -2
- package/src/components/DataTable/hooks/{__tests__/useTableHandlers.test.ts → useTableHandlers.test.ts} +25 -4
- package/src/components/DataTable/hooks/useTableHandlers.ts +5 -2
- package/src/components/DataTable/index.ts +18 -17
- package/src/components/DataTable/{__tests__/keyboard.test.tsx → keyboard.test.tsx} +41 -63
- package/src/components/DataTable/{__tests__/mocks → mocks}/MockRBACProvider.tsx +1 -1
- package/src/components/DataTable/{__tests__/pagination.modes.test.tsx → pagination.modes.test.tsx} +6 -6
- package/src/components/DataTable/{__tests__/ssr.strict-mode.test.tsx → ssr.strict-mode.test.tsx} +2 -2
- package/src/components/DataTable/{__tests__/styles.test.ts → styles.test.ts} +1 -4
- package/src/components/DataTable/styles.ts +0 -1
- package/src/components/DataTable/test-utils/MockDataTableComponents.tsx +55 -0
- package/src/components/DataTable/{__tests__/test-utils → test-utils}/dataFactories.ts +2 -2
- package/src/components/DataTable/test-utils/featureConfig.ts +10 -0
- package/src/components/DataTable/{__tests__/test-utils/sharedTestUtils.tsx → test-utils/sharedTestUtils.ts} +97 -66
- package/src/components/DataTable/{__tests__/test-utils.ts → test-utils.ts} +1 -1
- package/src/components/DataTable/types/actions.ts +71 -0
- package/src/components/DataTable/types/base.ts +39 -0
- package/src/components/DataTable/types/columns.ts +125 -0
- package/src/components/DataTable/types/export.ts +32 -0
- package/src/components/DataTable/types/features.ts +81 -0
- package/src/components/DataTable/types/hierarchical.ts +44 -0
- package/src/components/DataTable/types/index.ts +43 -0
- package/src/components/DataTable/types/pagination.ts +85 -0
- package/src/components/DataTable/types/performance.ts +47 -0
- package/src/components/DataTable/types/props.ts +62 -0
- package/src/components/DataTable/types/rbac.ts +45 -0
- package/src/components/DataTable/{components/__tests__ → ui/layout}/DataTableCore.test.tsx +430 -28
- package/src/components/DataTable/ui/layout/DataTableCore.tsx +345 -0
- package/src/components/DataTable/{components/__tests__ → ui/layout}/DataTableErrorBoundary.test.tsx +4 -4
- package/src/components/DataTable/{components → ui/layout}/DataTableErrorBoundary.tsx +7 -7
- package/src/components/DataTable/ui/layout/DataTableLayout.test.tsx +1352 -0
- package/src/components/DataTable/ui/layout/DataTableLayout.tsx +661 -0
- package/src/components/DataTable/ui/modals/BulkDeleteConfirmDialog.test.tsx +91 -0
- package/src/components/DataTable/ui/modals/BulkDeleteConfirmDialog.tsx +43 -0
- package/src/components/DataTable/ui/modals/DataTableModals.test.tsx +749 -0
- package/src/components/DataTable/{components → ui/modals}/DataTableModals.tsx +36 -28
- package/src/components/DataTable/ui/modals/ImportModal.test.tsx +1834 -0
- package/src/components/DataTable/ui/modals/ImportModal.tsx +197 -0
- package/src/components/DataTable/ui/modals/ImportModalFailedRowsSection.tsx +60 -0
- package/src/components/DataTable/ui/modals/ImportModalFileSection.tsx +148 -0
- package/src/components/DataTable/ui/modals/ImportModalPreviewSection.tsx +60 -0
- package/src/components/DataTable/ui/modals/ImportModalSummarySection.tsx +59 -0
- package/src/components/DataTable/ui/modals/importModalPersistence.ts +73 -0
- package/src/components/DataTable/{components/__tests__ → ui/shared}/AccessDeniedPage.test.tsx +2 -2
- package/src/components/DataTable/{components → ui/shared}/AccessDeniedPage.tsx +2 -2
- package/src/components/DataTable/{components/__tests__ → ui/shared}/ActionButtons.test.tsx +6 -4
- package/src/components/DataTable/{components → ui/shared}/ActionButtons.tsx +4 -4
- package/src/components/DataTable/{components/__tests__ → ui/shared}/ColumnFilter.test.tsx +29 -16
- package/src/components/DataTable/{components → ui/shared}/ColumnFilter.tsx +4 -4
- package/src/components/DataTable/{components/__tests__ → ui/shared}/PaginationControls.test.tsx +38 -16
- package/src/components/DataTable/{components → ui/shared}/PaginationControls.tsx +21 -15
- package/src/components/DataTable/{components/__tests__ → ui/shared}/SortIndicator.test.tsx +2 -2
- package/src/components/DataTable/{components → ui/shared}/SortIndicator.tsx +1 -1
- package/src/components/DataTable/{components/__tests__ → ui/table}/EditFields.test.tsx +3 -3
- package/src/components/DataTable/{components → ui/table}/EditFields.tsx +138 -69
- package/src/components/DataTable/{components/__tests__ → ui/table}/EditableRow.test.tsx +36 -27
- package/src/components/DataTable/{components → ui/table}/EditableRow.tsx +86 -104
- package/src/components/DataTable/{components/__tests__ → ui/table}/EmptyState.test.tsx +2 -62
- package/src/components/DataTable/{components → ui/table}/EmptyState.tsx +7 -15
- package/src/components/DataTable/{components/__tests__ → ui/table}/FilterRow.test.tsx +5 -4
- package/src/components/DataTable/{components → ui/table}/FilterRow.tsx +3 -3
- package/src/components/DataTable/{components/__tests__ → ui/table}/LoadingState.test.tsx +6 -10
- package/src/components/DataTable/{components → ui/table}/LoadingState.tsx +4 -4
- package/src/components/DataTable/{components/__tests__ → ui/table}/RowComponent.test.tsx +412 -17
- package/src/components/DataTable/{components → ui/table}/RowComponent.tsx +183 -177
- package/src/components/DataTable/{components/__tests__ → ui/table}/UnifiedTableBody.test.tsx +425 -16
- package/src/components/DataTable/ui/table/UnifiedTableBody.tsx +440 -0
- package/src/components/DataTable/{components/__tests__ → ui/table}/cellValueUtils.test.ts +2 -2
- package/src/components/DataTable/{components → ui/table}/cellValueUtils.ts +1 -1
- package/src/components/DataTable/{components/__tests__ → ui/toolbar}/BulkOperationsDropdown.test.tsx +12 -5
- package/src/components/DataTable/{components → ui/toolbar}/BulkOperationsDropdown.tsx +3 -3
- package/src/components/DataTable/{components/__tests__ → ui/toolbar}/ColumnVisibilityDropdown.test.tsx +7 -4
- package/src/components/DataTable/{components → ui/toolbar}/ColumnVisibilityDropdown.tsx +7 -7
- package/src/components/DataTable/{components/__tests__ → ui/toolbar}/DataTableToolbar.test.tsx +4 -4
- package/src/components/DataTable/{components → ui/toolbar}/DataTableToolbar.tsx +4 -4
- package/src/components/DataTable/ui/toolbar/GroupingDropdown.test.tsx +621 -0
- package/src/components/DataTable/ui/toolbar/GroupingDropdown.tsx +107 -0
- package/src/components/DataTable/utils/{__tests__/a11yUtils.test.ts → a11yUtils.test.ts} +2 -2
- package/src/components/DataTable/utils/{__tests__/aggregationUtils.test.ts → aggregationUtils.test.ts} +3 -3
- package/src/components/DataTable/utils/{__tests__/columnUtils.test.ts → columnUtils.test.ts} +2 -2
- package/src/components/DataTable/utils/csvParse.test.ts +74 -0
- package/src/components/DataTable/utils/csvParse.ts +65 -0
- package/src/components/DataTable/utils/{__tests__/errorHandling.test.ts → errorHandling.test.ts} +2 -2
- package/src/components/DataTable/utils/{__tests__/exportUtils.test.ts → exportUtils.test.ts} +3 -3
- package/src/components/DataTable/utils/{__tests__/flexibleImport.test.ts → flexibleImport.test.ts} +2 -2
- package/src/components/DataTable/utils/flexibleImport.ts +3 -186
- package/src/components/DataTable/utils/{__tests__/hierarchicalSorting.test.ts → hierarchicalSorting.test.ts} +3 -3
- package/src/components/DataTable/utils/{__tests__/hierarchicalUtils.test.ts → hierarchicalUtils.test.ts} +3 -3
- package/src/components/DataTable/utils/importDateParser.test.ts +162 -0
- package/src/components/DataTable/utils/importDateParser.ts +114 -0
- package/src/components/DataTable/utils/importValueParser.test.ts +138 -0
- package/src/components/DataTable/utils/importValueParser.ts +91 -0
- package/src/components/DataTable/utils/{__tests__/paginationUtils.test.ts → paginationUtils.test.ts} +2 -2
- package/src/components/DataTable/utils/paginationUtils.ts +6 -3
- package/src/components/DataTable/utils/{__tests__/performanceUtils.test.ts → performanceUtils.test.ts} +3 -3
- package/src/components/DataTable/utils/{__tests__/rowUtils.test.ts → rowUtils.test.ts} +3 -3
- package/src/components/DataTable/utils/{__tests__/selectFieldUtils.test.ts → selectFieldUtils.test.ts} +66 -3
- package/src/components/DataTable/utils/selectFieldUtils.ts +97 -60
- package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +1 -1
- package/src/components/DateTimeField/DateTimeField.test.tsx +1 -1
- package/src/components/Dialog/Dialog.test-utils.ts +49 -0
- package/src/components/Dialog/Dialog.test.tsx +896 -89
- package/src/components/Dialog/Dialog.tsx +174 -882
- package/src/components/Dialog/dialogLock.test.ts +238 -0
- package/src/components/Dialog/dialogLock.ts +98 -0
- package/src/components/Dialog/index.ts +2 -0
- package/src/components/Dialog/useDialogDimensions.test.ts +163 -0
- package/src/components/Dialog/useDialogDimensions.ts +140 -0
- package/src/components/Dialog/useDialogLifecycle.test.ts +358 -0
- package/src/components/Dialog/useDialogLifecycle.ts +135 -0
- package/src/components/Dialog/useDialogPersistence.test.ts +381 -0
- package/src/components/Dialog/useDialogPersistence.ts +357 -0
- package/src/components/FileDisplay/FileDisplay.test.tsx +40 -40
- package/src/components/FileDisplay/FileDisplay.tsx +24 -656
- package/src/components/FileDisplay/FileDisplayContent.test.tsx +395 -0
- package/src/components/FileDisplay/FileDisplayContent.tsx +242 -0
- package/src/components/FileDisplay/FileDisplayDeleteConfirmDialog.test.tsx +74 -0
- package/src/components/FileDisplay/FileDisplayDeleteConfirmDialog.tsx +38 -0
- package/src/components/FileDisplay/FileDisplayEmptyView.test.tsx +33 -0
- package/src/components/FileDisplay/FileDisplayEmptyView.tsx +33 -0
- package/src/components/FileDisplay/FileDisplayErrorView.test.tsx +71 -0
- package/src/components/FileDisplay/FileDisplayErrorView.tsx +50 -0
- package/src/components/FileDisplay/FileDisplayLoadingFallbackView.test.tsx +22 -0
- package/src/components/FileDisplay/FileDisplayLoadingFallbackView.tsx +22 -0
- package/src/components/FileDisplay/FileDisplayLoadingView.test.tsx +21 -0
- package/src/components/FileDisplay/FileDisplayLoadingView.tsx +23 -0
- package/src/components/FileDisplay/FileDisplayMultipleFilesView.test.tsx +101 -0
- package/src/components/FileDisplay/FileDisplayMultipleFilesView.tsx +109 -0
- package/src/components/FileDisplay/FileDisplaySingleDocumentLinkView.test.tsx +58 -0
- package/src/components/FileDisplay/FileDisplaySingleDocumentLinkView.tsx +48 -0
- package/src/components/FileDisplay/FileDisplaySingleFileWithActionsView.test.tsx +111 -0
- package/src/components/FileDisplay/FileDisplaySingleFileWithActionsView.tsx +270 -0
- package/src/components/FileDisplay/FileDisplaySingleImageView.test.tsx +78 -0
- package/src/components/FileDisplay/FileDisplaySingleImageView.tsx +67 -0
- package/src/components/FileDisplay/fallbackUtils.test.ts +50 -0
- package/src/components/FileDisplay/fallbackUtils.ts +44 -0
- package/src/components/FileDisplay/fetchFileDisplayData.ts +24 -0
- package/src/components/FileDisplay/fetchFileDisplayData.unit.test.ts +183 -0
- package/src/components/FileDisplay/fileDisplayUtils.test.ts +58 -0
- package/src/components/FileDisplay/fileDisplayUtils.ts +24 -0
- package/src/{hooks/__tests__ → components/FileDisplay}/useFileDisplay.test.ts +40 -42
- package/src/components/FileDisplay/useFileDisplay.ts +515 -0
- package/src/{hooks/__tests__ → components/FileDisplay}/useFileDisplay.unit.test.ts +406 -77
- package/src/components/FileDisplay/useFileDisplayData.ts +126 -0
- package/src/{hooks/public → components/FileDisplay}/usePublicFileDisplay.test.ts +94 -88
- package/src/components/FileDisplay/usePublicFileDisplay.ts +579 -0
- package/src/components/FileUpload/FileUpload.test.tsx +16 -10
- package/src/components/FileUpload/FileUpload.tsx +107 -525
- package/src/components/FileUpload/FileUploadDropZone.tsx +112 -0
- package/src/components/FileUpload/FileUploadProgressItem.tsx +86 -0
- package/src/components/FileUpload/FileUploadProgressList.tsx +40 -0
- package/src/components/FileUpload/useFileUploadManager.test.ts +308 -0
- package/src/components/FileUpload/useFileUploadManager.ts +454 -0
- package/src/components/FileUpload/useResolvedAppId.test.ts +102 -0
- package/src/components/FileUpload/useResolvedAppId.ts +77 -0
- package/src/components/Footer/Footer.test.tsx +6 -292
- package/src/components/Footer/Footer.tsx +8 -125
- package/src/components/Form/Form.test.tsx +44 -27
- package/src/components/Form/Form.tsx +64 -287
- package/src/components/Form/useFormPersistence.ts +257 -0
- package/src/components/Header/Header.test.tsx +17 -18
- package/src/components/Header/Header.tsx +10 -1
- package/src/components/Input/Input.tsx +1 -1
- package/src/components/Label/Label.test.tsx +1 -1
- package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +1 -1
- package/src/components/NavigationMenu/HierarchicalNavItem.tsx +104 -0
- package/src/components/NavigationMenu/NavigationMenu.test.tsx +1029 -26
- package/src/components/NavigationMenu/NavigationMenu.tsx +61 -361
- package/src/components/NavigationMenu/index.ts +6 -1
- package/src/components/NavigationMenu/navigationPermissionHelper.ts +188 -0
- package/src/components/NavigationMenu/{__tests__/useNavigationFiltering.test.ts → useNavigationFiltering.test.ts} +68 -53
- package/src/components/NavigationMenu/useNavigationFiltering.ts +197 -296
- package/src/components/NavigationMenu/useNavigationScope.ts +125 -0
- package/src/components/PaceAppLayout/PaceAppLayout.edge-cases.test.tsx +77 -62
- package/src/components/PaceAppLayout/PaceAppLayout.integration.test.tsx +3 -3
- package/src/components/PaceAppLayout/PaceAppLayout.security.test.tsx +16 -19
- package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +529 -5
- package/src/components/PaceAppLayout/PaceAppLayout.tsx +280 -756
- package/src/components/PaceAppLayout/useFilteredNavItems.ts +304 -0
- package/src/components/PaceAppLayout/usePaceAppLayoutConfig.ts +142 -0
- package/src/components/PaceAppLayout/usePaceAppLayoutGate.tsx +150 -0
- package/src/components/PaceAppLayout/usePaceAppLayoutPermissions.ts +162 -0
- package/src/components/PaceAppLayout/usePaceAppLayoutScope.ts +79 -0
- package/src/components/PaceAppLayout/useRoleBasedRouteAccess.ts +157 -0
- package/src/components/PaceAppLayout/useSuperAdminFallback.ts +58 -0
- package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +31 -25
- package/src/components/PaceLoginPage/PaceLoginPage.tsx +31 -122
- package/src/components/PaceLoginPage/useLoginAppAccess.ts +153 -0
- package/src/components/Progress/Progress.tsx +1 -2
- package/src/components/ProtectedRoute/ProtectedRoute.tsx +29 -235
- package/src/components/ProtectedRoute/useProtectedRouteState.ts +128 -0
- package/src/components/ProtectedRoute/useVisibilityRedirectGrace.ts +89 -0
- package/src/components/PublicLayout/PublicLayout.test.tsx +217 -36
- package/src/components/PublicLayout/PublicPageLayout.tsx +132 -73
- package/src/components/PublicLayout/PublicPageProvider.tsx +5 -1
- package/src/components/Select/Select.test.tsx +1 -1
- package/src/components/Select/Select.tsx +28 -18
- package/src/components/Select/{__tests__/context.test.tsx → context.test.tsx} +3 -3
- package/src/components/Select/{utils/__tests__/text.test.tsx → text.test.tsx} +2 -2
- package/src/components/Select/{utils/text.ts → text.ts} +1 -1
- package/src/components/Select/{hooks/__tests__/useSelectEvents.test.ts → useSelectEvents.test.ts} +5 -5
- package/src/components/Select/{hooks/useSelectEvents.ts → useSelectEvents.ts} +2 -2
- package/src/components/Select/{hooks/__tests__/useSelectSearch.test.tsx → useSelectSearch.test.tsx} +7 -7
- package/src/components/Select/{hooks/useSelectSearch.ts → useSelectSearch.ts} +2 -2
- package/src/components/Select/{hooks/__tests__/useSelectState.test.ts → useSelectState.test.ts} +16 -2
- package/src/components/Select/{hooks/useSelectState.ts → useSelectState.ts} +3 -3
- package/src/components/Table/Table.test.tsx +348 -0
- package/src/components/Tabs/Tabs.test.tsx +270 -0
- package/src/components/Tabs/Tabs.tsx +1 -1
- package/src/components/Toast/Toast.test.tsx +420 -0
- package/src/components/{__tests__/index.test.ts → index.test.ts} +2 -2
- package/src/constants/{__tests__/performance.test.ts → performance.test.ts} +2 -2
- package/src/hooks/{__tests__/ServiceHooks.test.tsx → ServiceHooks.test.tsx} +8 -8
- package/src/hooks/{__tests__/hooks.integration.test.tsx → hooks.integration.test.tsx} +11 -11
- package/src/hooks/index.ts +7 -4
- package/src/hooks/{__tests__/index.unit.test.ts → index.unit.test.ts} +2 -2
- package/src/hooks/public/usePublicEvent.test.ts +1 -1
- package/src/hooks/public/usePublicEventLogo.test.ts +1 -1
- package/src/hooks/public/usePublicRouteParams.test.ts +1 -1
- package/src/hooks/services/useAuth.ts +9 -7
- package/src/hooks/useAddressAutocomplete.test.ts +22 -22
- package/src/hooks/useAddressAutocomplete.ts +90 -75
- package/src/hooks/{__tests__/useAppConfig.unit.test.ts → useAppConfig.unit.test.ts} +328 -22
- package/src/hooks/{__tests__/useComponentPerformance.unit.test.tsx → useComponentPerformance.unit.test.tsx} +27 -41
- package/src/hooks/useDataTablePerformance.ts +100 -120
- package/src/hooks/{__tests__/useDataTablePerformance.unit.test.ts → useDataTablePerformance.unit.test.ts} +5 -5
- package/src/hooks/{__tests__/useDataTableState.test.ts → useDataTableState.test.ts} +2 -2
- package/src/hooks/{__tests__/useDebounce.unit.test.ts → useDebounce.unit.test.ts} +2 -2
- package/src/hooks/useEventTheme.test.ts +4 -1
- package/src/hooks/useEventTheme.ts +49 -21
- package/src/hooks/useEvents.ts +41 -1
- package/src/hooks/{__tests__/useEvents.unit.test.ts → useEvents.unit.test.ts} +5 -5
- package/src/hooks/useFileReference.test.ts +44 -41
- package/src/hooks/useFileReference.ts +182 -173
- package/src/hooks/useFileUrl.ts +1 -1
- package/src/hooks/{__tests__/useFileUrl.unit.test.ts → useFileUrl.unit.test.ts} +26 -36
- package/src/hooks/{__tests__/useFileUrlCache.test.ts → useFileUrlCache.test.ts} +8 -8
- package/src/hooks/useFileUrlCache.ts +1 -1
- package/src/hooks/{__tests__/useFocusManagement.unit.test.ts → useFocusManagement.unit.test.ts} +2 -2
- package/src/hooks/{__tests__/useFocusTrap.unit.test.tsx → useFocusTrap.unit.test.tsx} +2 -2
- package/src/hooks/{__tests__/useFormDialog.test.ts → useFormDialog.test.ts} +2 -2
- package/src/hooks/useInactivityTracker.ts +138 -131
- package/src/hooks/{__tests__/useInactivityTracker.unit.test.ts → useInactivityTracker.unit.test.ts} +3 -3
- package/src/hooks/{__tests__/useIsMobile.unit.test.ts → useIsMobile.unit.test.ts} +2 -2
- package/src/hooks/useIsPrint.ts +62 -0
- package/src/hooks/useIsPrint.unit.test.ts +545 -0
- package/src/hooks/{__tests__/useKeyboardShortcuts.unit.test.ts → useKeyboardShortcuts.unit.test.ts} +2 -2
- package/src/hooks/{__tests__/useOrganisationPermissions.unit.test.tsx → useOrganisationPermissions.unit.test.tsx} +4 -4
- package/src/hooks/useOrganisationSecurity.test.ts +3 -3
- package/src/hooks/useOrganisationSecurity.ts +190 -201
- package/src/hooks/{__tests__/useOrganisationSecurity.unit.test.tsx → useOrganisationSecurity.unit.test.tsx} +61 -63
- package/src/hooks/{__tests__/useOrganisations.unit.test.ts → useOrganisations.unit.test.ts} +5 -5
- package/src/hooks/{__tests__/usePerformanceMonitor.unit.test.ts → usePerformanceMonitor.unit.test.ts} +13 -14
- package/src/hooks/{__tests__/usePermissionCache.test.ts → usePermissionCache.test.ts} +26 -27
- package/src/hooks/usePermissionCache.ts +276 -271
- package/src/hooks/{__tests__/usePreventTabReload.test.ts → usePreventTabReload.test.ts} +2 -2
- package/src/hooks/{__tests__/usePublicEvent.simple.test.ts → usePublicEvent.simple.test.ts} +4 -4
- package/src/hooks/{__tests__/usePublicEvent.test.ts → usePublicEvent.test.ts} +4 -4
- package/src/hooks/{__tests__/usePublicEvent.unit.test.ts → usePublicEvent.unit.test.ts} +4 -4
- package/src/hooks/{__tests__/usePublicFileDisplay.test.ts → usePublicFileDisplay.test.ts} +12 -12
- package/src/hooks/{__tests__/usePublicRouteParams.unit.test.ts → usePublicRouteParams.unit.test.ts} +3 -3
- package/src/hooks/{__tests__/useQueryCache.test.ts → useQueryCache.test.ts} +2 -2
- package/src/hooks/useQueryCache.ts +0 -2
- package/src/hooks/{__tests__/useRBAC.unit.test.ts → useRBAC.unit.test.ts} +55 -38
- package/src/hooks/{__tests__/useSessionDraft.test.ts → useSessionDraft.test.ts} +2 -2
- package/src/hooks/{__tests__/useSessionRestoration.unit.test.tsx → useSessionRestoration.unit.test.tsx} +10 -19
- package/src/hooks/useStorage.ts +21 -16
- package/src/hooks/{__tests__/useStorage.unit.test.ts → useStorage.unit.test.ts} +38 -75
- package/src/hooks/{__tests__/useToast.test.ts → useToast.test.ts} +2 -2
- package/src/hooks/{__tests__/useToast.unit.test.tsx → useToast.unit.test.tsx} +2 -2
- package/src/hooks/{__tests__/useZodForm.unit.test.tsx → useZodForm.unit.test.tsx} +2 -2
- package/src/icons/{__tests__/index.test.ts → index.test.ts} +2 -2
- package/src/icons/index.ts +2 -0
- package/src/{__tests__/index.test.ts → index.test.ts} +3 -7
- package/src/index.ts +15 -7
- package/src/providers/{__tests__/AuthProvider.test.tsx → AuthProvider.test.tsx} +3 -3
- package/src/providers/{__tests__/EventProvider.test.tsx → EventProvider.test.tsx} +3 -3
- package/src/providers/InactivityProvider.test-helper.tsx +40 -0
- package/src/providers/{__tests__/InactivityProvider.test.tsx → InactivityProvider.test.tsx} +14 -21
- package/src/providers/{__tests__/ProviderLifecycle.test.tsx → ProviderLifecycle.test.tsx} +4 -4
- package/src/providers/{__tests__/UnifiedAuthProvider.test.tsx → UnifiedAuthProvider.test.tsx} +1 -1
- package/src/providers/{__tests__/index.test.ts → index.test.ts} +2 -2
- package/src/providers/services/{__tests__/AuthServiceProvider.integration.test.tsx → AuthServiceProvider.integration.test.tsx} +4 -4
- package/src/providers/services/{__tests__/AuthServiceProvider.test.tsx → AuthServiceProvider.test.tsx} +7 -7
- package/src/providers/services/{__tests__/EventServiceProvider.test.tsx → EventServiceProvider.test.tsx} +7 -7
- package/src/providers/services/{__tests__/InactivityServiceProvider.test.tsx → InactivityServiceProvider.test.tsx} +5 -5
- package/src/providers/services/{__tests__/OrganisationServiceProvider.test.tsx → OrganisationServiceProvider.test.tsx} +6 -6
- package/src/providers/services/UnifiedAuthContext.ts +30 -27
- package/src/providers/services/{__tests__/UnifiedAuthProvider.advanced.test.tsx → UnifiedAuthProvider.advanced.test.tsx} +8 -9
- package/src/providers/services/{__tests__/UnifiedAuthProvider.appId.test.tsx → UnifiedAuthProvider.appId.test.tsx} +25 -25
- package/src/providers/services/{__tests__/UnifiedAuthProvider.integration.test.tsx → UnifiedAuthProvider.integration.test.tsx} +14 -11
- package/src/providers/services/UnifiedAuthProvider.tsx +115 -360
- package/src/providers/services/{__tests__/contexts.test.tsx → contexts.test.tsx} +6 -6
- package/src/providers/services/{__tests__/useUnifiedAuth.test.tsx → useUnifiedAuth.test.tsx} +6 -6
- package/src/providers/services/useUnifiedAuthContextValue.ts +279 -0
- package/src/providers/useInactivity.test-helper.ts +27 -0
- package/src/rbac/{__tests__/adapters.comprehensive.test.tsx → adapters.comprehensive.test.tsx} +24 -24
- package/src/rbac/adapters.test.tsx +22 -22
- package/src/rbac/adapters.tsx +29 -29
- package/src/rbac/api.test.ts +973 -42
- package/src/rbac/api.ts +228 -253
- package/src/rbac/{__tests__/audit-batched.test.ts → audit-batched.test.ts} +6 -6
- package/src/rbac/audit.ts +4 -1
- package/src/rbac/{__tests__/auth-rbac-security.integration.test.tsx → auth-rbac-security.integration.test.tsx} +1 -1
- package/src/rbac/{__tests__/auth-rbac.e2e.test.tsx → auth-rbac.e2e.test.tsx} +27 -34
- package/src/rbac/cache-invalidation.test.ts +715 -0
- package/src/rbac/components/{__tests__/AccessDenied.test.tsx → AccessDenied.test.tsx} +3 -3
- package/src/rbac/components/{__tests__/NavigationGuard.test.tsx → NavigationGuard.test.tsx} +13 -11
- package/src/{__tests__/rbac/PagePermissionGuard.test.tsx → rbac/components/PagePermissionGuard.guard.test.tsx} +33 -19
- package/src/rbac/components/{__tests__/PagePermissionGuard.performance.test.tsx → PagePermissionGuard.performance.test.tsx} +30 -9
- package/src/rbac/components/{__tests__/PagePermissionGuard.race-condition.test.tsx → PagePermissionGuard.race-condition.test.tsx} +7 -7
- package/src/rbac/components/{__tests__/PagePermissionGuard.test.tsx → PagePermissionGuard.test.tsx} +10 -10
- package/src/rbac/components/PagePermissionGuard.tsx +177 -372
- package/src/rbac/components/{__tests__/PagePermissionGuard.verification.test.tsx → PagePermissionGuard.verification.test.tsx} +7 -7
- package/src/rbac/config.ts +58 -18
- package/src/rbac/{__tests__/engine.comprehensive.test.ts → engine.comprehensive.test.ts} +3 -3
- package/src/rbac/engine.test.ts +494 -0
- package/src/rbac/errors.ts +89 -55
- package/src/rbac/hooks/permissions/runPermissionCheck.ts +77 -0
- package/src/rbac/hooks/permissions/{__tests__/useAccessLevel.test.ts → useAccessLevel.test.ts} +40 -40
- package/src/rbac/hooks/permissions/useAccessLevel.ts +16 -6
- package/src/rbac/hooks/permissions/{__tests__/useCan.test.ts → useCan.test.ts} +41 -41
- package/src/rbac/hooks/permissions/useCan.ts +170 -252
- package/src/rbac/hooks/permissions/{__tests__/useMultiplePermissions.test.ts → useMultiplePermissions.test.ts} +49 -49
- package/src/rbac/hooks/permissions/useMultiplePermissions.ts +6 -2
- package/src/rbac/hooks/permissions/{__tests__/usePermissions.test.ts → usePermissions.test.ts} +10 -12
- package/src/rbac/hooks/permissions/usePermissions.ts +36 -65
- package/src/rbac/hooks/useCan.test.ts +42 -42
- package/src/rbac/hooks/usePageAccessLogging.ts +160 -0
- package/src/rbac/hooks/usePageGuardScope.ts +117 -0
- package/src/rbac/hooks/usePagePermissionCheck.ts +67 -0
- package/src/rbac/hooks/{__tests__/usePermissions.integration.test.ts → usePermissions.integration.test.ts} +9 -9
- package/src/{__tests__/hooks/usePermissions.test.ts → rbac/hooks/usePermissions.stability.test.ts} +18 -18
- package/src/rbac/hooks/usePermissions.test.ts +54 -54
- package/src/rbac/hooks/useRBAC.test.ts +313 -217
- package/src/rbac/hooks/useRBAC.ts +145 -81
- package/src/rbac/hooks/useResourcePermissions.test.ts +25 -25
- package/src/rbac/hooks/useResourcePermissions.ts +68 -134
- package/src/rbac/hooks/useResourcePermissionsSuperAdmin.ts +67 -0
- package/src/rbac/hooks/useRoleManagement.test.ts +27 -112
- package/src/rbac/hooks/useRoleManagement.ts +153 -585
- package/src/rbac/hooks/{__tests__/useSecureSupabase.test.ts → useSecureSupabase.test.ts} +17 -17
- package/src/rbac/hooks/useSecureSupabase.ts +10 -2
- package/src/rbac/hooks/useSuperAdminCheck.ts +80 -0
- package/src/rbac/{__tests__/performance.test.ts → performance.test.ts} +1 -1
- package/src/rbac/{__tests__/rbac-core.test.tsx → rbac-core.test.tsx} +3 -3
- package/src/rbac/{__tests__/rbac-engine-core-logic.test.ts → rbac-engine-core-logic.test.ts} +2 -2
- package/src/rbac/{__tests__/rbac-engine-simplified.test.ts → rbac-engine-simplified.test.ts} +3 -3
- package/src/rbac/{__tests__/rbac-functions.test.ts → rbac-functions.test.ts} +57 -0
- package/src/rbac/{__tests__/rbac-role-isolation.test.ts → rbac-role-isolation.test.ts} +2 -2
- package/src/rbac/request-deduplication.test.ts +14 -9
- package/src/rbac/request-deduplication.ts +5 -4
- package/src/rbac/{__tests__/scenarios.user-role.test.tsx → scenarios.user-role.test.tsx} +23 -23
- package/src/rbac/secureClient.test.ts +514 -83
- package/src/rbac/secureClient.ts +8 -2
- package/src/rbac/security.test.ts +323 -0
- package/src/rbac/types/roleManagement.ts +66 -0
- package/src/rbac/utils/{__tests__/clientSecurity.test.ts → clientSecurity.test.ts} +4 -4
- package/src/rbac/utils/{__tests__/contextValidator.test.ts → contextValidator.test.ts} +4 -4
- package/src/rbac/utils/contextValidator.ts +5 -1
- package/src/rbac/utils/{__tests__/deep-equal.test.ts → deep-equal.test.ts} +1 -1
- package/src/rbac/utils/{__tests__/eventContext.test.ts → eventContext.test.ts} +36 -21
- package/src/rbac/utils/eventContext.ts +37 -33
- package/src/rbac/utils/fetchPermissionMap.ts +13 -0
- package/src/rbac/utils/permissionMapHelpers.ts +34 -0
- package/src/rbac/utils/roleManagementRpc.ts +303 -0
- package/src/services/{__tests__/AuthService.edge-cases.test.ts → AuthService.edge-cases.test.ts} +19 -19
- package/src/services/{__tests__/AuthService.restoreSession.test.ts → AuthService.restoreSession.test.ts} +2 -2
- package/src/services/{__tests__/AuthService.test.ts → AuthService.test.ts} +89 -55
- package/src/services/AuthService.ts +184 -205
- package/src/services/{__tests__/BaseService.edge-cases.test.ts → BaseService.edge-cases.test.ts} +3 -3
- package/src/services/{__tests__/BaseService.test.ts → BaseService.test.ts} +2 -2
- package/src/services/{__tests__/EventService.edge-cases.test.ts → EventService.edge-cases.test.ts} +27 -24
- package/src/services/{__tests__/EventService.eventColours.test.ts → EventService.eventColours.test.ts} +1 -1
- package/src/services/{__tests__/EventService.test.ts → EventService.test.ts} +256 -24
- package/src/services/EventService.ts +242 -312
- package/src/services/{__tests__/InactivityService.edge-cases.test.ts → InactivityService.edge-cases.test.ts} +3 -3
- package/src/services/{__tests__/InactivityService.lifecycle.test.ts → InactivityService.lifecycle.test.ts} +2 -2
- package/src/services/{__tests__/InactivityService.test.ts → InactivityService.test.ts} +179 -4
- package/src/services/InactivityService.ts +172 -213
- package/src/services/{__tests__/OrganisationService.edge-cases.test.ts → OrganisationService.edge-cases.test.ts} +5 -5
- package/src/services/{__tests__/OrganisationService.pagination.test.ts → OrganisationService.pagination.test.ts} +4 -4
- package/src/services/{__tests__/OrganisationService.test.ts → OrganisationService.test.ts} +410 -7
- package/src/services/OrganisationService.ts +184 -238
- package/src/services/base/BaseService.test.ts +1 -1
- package/src/services/interfaces/{__tests__/IAuthService.test.ts → IAuthService.test.ts} +21 -27
- package/src/services/interfaces/IAuthService.ts +10 -9
- package/src/services/interfaces/{__tests__/IEventService.test.ts → IEventService.test.ts} +4 -4
- package/src/services/interfaces/{__tests__/IInactivityService.test.ts → IInactivityService.test.ts} +3 -3
- package/src/services/interfaces/{__tests__/IOrganisationService.test.ts → IOrganisationService.test.ts} +3 -3
- package/src/styles/core.css +243 -12
- package/src/theming/{__tests__/parseEventColours.test.ts → parseEventColours.test.ts} +1 -1
- package/src/theming/{__tests__/runtime.test.ts → runtime.test.ts} +8 -17
- package/src/theming/runtime.ts +71 -2
- package/src/types/api-result.ts +53 -0
- package/src/types/{__tests__/core.test.ts → core.test.ts} +2 -2
- package/src/types/{__tests__/database-generated.test.ts → database-generated.test.ts} +3 -3
- package/src/types/database.generated.ts +45 -10
- package/src/types/event.ts +38 -18
- package/src/types/{__tests__/file-reference.test.ts → file-reference.test.ts} +13 -13
- package/src/types/file-reference.ts +37 -12
- package/src/types/{__tests__/guards.test.ts → guards.test.ts} +2 -2
- package/src/types/{__tests__/index.test.ts → index.test.ts} +2 -2
- package/src/types/index.ts +3 -0
- package/src/types/{__tests__/organisation.roles.test.ts → organisation.roles.test.ts} +1 -1
- package/src/types/{__tests__/organisation.test.ts → organisation.test.ts} +3 -31
- package/src/types/organisation.ts +15 -15
- package/src/types/supabase.ts +13 -4
- package/src/types/{__tests__/theme.test.ts → theme.test.ts} +1 -1
- package/src/types/{__tests__/type-validation.test.ts → type-validation.test.ts} +1 -1
- package/src/types/{__tests__/validation.test.ts → validation.test.ts} +2 -2
- package/src/utils/app/appIdResolver.test.ts +98 -71
- package/src/utils/app/appIdResolver.ts +31 -20
- package/src/utils/{__tests__/appConfig.unit.test.ts → appConfig.unit.test.ts} +1 -1
- package/src/utils/{__tests__/audit.unit.test.ts → audit.unit.test.ts} +1 -1
- package/src/utils/{__tests__/auth-utils.unit.test.ts → auth-utils.unit.test.ts} +16 -17
- package/src/utils/{__tests__/bundleAnalysis.unit.test.ts → bundleAnalysis.unit.test.ts} +35 -35
- package/src/utils/{__tests__/cn.unit.test.ts → cn.unit.test.ts} +1 -1
- package/src/utils/context/organisationContext.test.ts +105 -91
- package/src/utils/context/organisationContext.ts +29 -40
- package/src/utils/core/{__tests__/cn.test.ts → cn.test.ts} +3 -3
- package/src/utils/core/{__tests__/debugLogger.test.ts → debugLogger.test.ts} +2 -2
- package/src/utils/core/{__tests__/logger.test.ts → logger.test.ts} +2 -2
- package/src/utils/core/mergeRefs.ts +24 -0
- package/src/utils/{__tests__/debugLogger.test.ts → debugLogger.test.ts} +1 -1
- package/src/utils/{__tests__/deviceFingerprint.unit.test.ts → deviceFingerprint.unit.test.ts} +1 -1
- package/src/utils/dynamic/createLazyComponent.tsx +9 -1
- package/src/utils/dynamic/{__tests__/dynamicUtils.test.ts → dynamicUtils.test.ts} +2 -2
- package/src/utils/dynamic/{__tests__/lazyLoad.test.tsx → lazyLoad.test.tsx} +2 -2
- package/src/utils/{__tests__/dynamicUtils.unit.test.ts → dynamicUtils.unit.test.ts} +1 -1
- package/src/utils/file-reference/{__tests__/file-reference.test.ts → file-reference.test.ts} +214 -289
- package/src/utils/file-reference/index.ts +330 -347
- package/src/utils/{__tests__/formatDate.unit.test.ts → formatDate.unit.test.ts} +2 -2
- package/src/utils/formatting/formatDateTimeTimezone.test.ts +1 -1
- package/src/utils/formatting/formatNumber.test.ts +1 -1
- package/src/utils/{__tests__/formatting.unit.test.ts → formatting.unit.test.ts} +1 -1
- package/src/utils/google-places/googlePlacesUtils.test.ts +70 -48
- package/src/utils/google-places/googlePlacesUtils.ts +67 -99
- package/src/utils/google-places/loadGoogleMapsScript.test.ts +25 -22
- package/src/utils/google-places/loadGoogleMapsScript.ts +138 -117
- package/src/utils/{__tests__/index.unit.test.ts → index.unit.test.ts} +1 -1
- package/src/utils/{__tests__/lazyLoad.unit.test.tsx → lazyLoad.unit.test.tsx} +13 -14
- package/src/utils/location/location.test.ts +1 -1
- package/src/utils/{__tests__/logger.unit.test.ts → logger.unit.test.ts} +1 -1
- package/src/utils/{__tests__/organisationContext.unit.test.ts → organisationContext.unit.test.ts} +37 -48
- package/src/utils/performance/{__tests__/bundleAnalysis.test.ts → bundleAnalysis.test.ts} +2 -2
- package/src/utils/performance/{__tests__/performanceBenchmark.test.ts → performanceBenchmark.test.ts} +2 -2
- package/src/utils/performance/{__tests__/performanceBudgets.test.ts → performanceBudgets.test.ts} +2 -2
- package/src/utils/{__tests__/performanceBenchmark.test.ts → performanceBenchmark.test.ts} +2 -2
- package/src/utils/{__tests__/performanceBudgets.unit.test.ts → performanceBudgets.unit.test.ts} +2 -2
- package/src/utils/{__tests__/permissionTypes.unit.test.ts → permissionTypes.unit.test.ts} +1 -1
- package/src/utils/{__tests__/permissionUtils.unit.test.ts → permissionUtils.unit.test.ts} +1 -1
- package/src/utils/permissions/{__tests__/permissionTypes.test.ts → permissionTypes.test.ts} +2 -2
- package/src/utils/persistence/{__tests__/keyDerivation.test.ts → keyDerivation.test.ts} +2 -2
- package/src/utils/persistence/{__tests__/sensitiveFieldDetection.test.ts → sensitiveFieldDetection.test.ts} +2 -2
- package/src/utils/{__tests__/request-deduplication.test.ts → request-deduplication.test.ts} +2 -2
- package/src/utils/{__tests__/sanitization.unit.test.ts → sanitization.unit.test.ts} +1 -1
- package/src/utils/{__tests__/schemaUtils.unit.test.ts → schemaUtils.unit.test.ts} +1 -1
- package/src/utils/{__tests__/secureDataAccess.unit.test.ts → secureDataAccess.unit.test.ts} +2 -2
- package/src/utils/{__tests__/secureErrors.unit.test.ts → secureErrors.unit.test.ts} +4 -4
- package/src/utils/{__tests__/secureStorage.unit.test.ts → secureStorage.unit.test.ts} +1 -1
- package/src/utils/security/auth-utils.ts +34 -23
- package/src/utils/security/secureDataAccess.ts +241 -281
- package/src/utils/security/secureErrors.test.ts +1 -1
- package/src/utils/security/secureStorage.test.ts +1 -1
- package/src/utils/security/security.test.ts +25 -17
- package/src/utils/security/security.ts +15 -18
- package/src/utils/security/securityMonitor.test.ts +1 -1
- package/src/utils/{__tests__/security.unit.test.ts → security.unit.test.ts} +21 -15
- package/src/utils/{__tests__/securityMonitor.unit.test.ts → securityMonitor.unit.test.ts} +1 -1
- package/src/utils/{__tests__/sessionTracking.unit.test.ts → sessionTracking.unit.test.ts} +12 -12
- package/src/utils/storage/{__tests__/config.unit.test.ts → config.unit.test.ts} +2 -2
- package/src/utils/storage/helpers.test.ts +88 -102
- package/src/utils/storage/helpers.ts +173 -251
- package/src/utils/storage/{__tests__/index.unit.test.ts → index.unit.test.ts} +3 -3
- package/src/utils/storage/types.ts +7 -0
- package/src/utils/supabase/createBaseClient.test.ts +1 -1
- package/src/utils/timezone/timezone.test.ts +1 -1
- package/src/utils/{__tests__/timezone.test.ts → timezone.test.ts} +2 -2
- package/src/utils/validation/{__tests__/common.test.ts → common.test.ts} +2 -2
- package/src/utils/validation/{__tests__/csrf.test.ts → csrf.test.ts} +56 -28
- package/src/utils/validation/csrf.ts +42 -41
- package/src/utils/validation/{__tests__/htmlSanitization.unit.test.ts → htmlSanitization.unit.test.ts} +2 -2
- package/src/utils/validation/{__tests__/passwordSchema.test.ts → passwordSchema.test.ts} +2 -2
- package/src/utils/validation/{__tests__/schema.test.ts → schema.test.ts} +2 -2
- package/src/utils/validation/{__tests__/sqlInjectionProtection.test.ts → sqlInjectionProtection.test.ts} +2 -2
- package/src/utils/validation/{__tests__/user.test.ts → user.test.ts} +2 -2
- package/src/utils/validation/{__tests__/validation.test.ts → validation.test.ts} +2 -2
- package/src/utils/validation/{__tests__/validationUtils.test.ts → validationUtils.test.ts} +2 -2
- package/src/utils/{__tests__/validation.unit.test.ts → validation.unit.test.ts} +1 -1
- package/src/utils/{__tests__/validationUtils.unit.test.ts → validationUtils.unit.test.ts} +5 -2
- package/dist/UnifiedAuthProvider-BBD2PS3Q.js +0 -7
- package/dist/chunk-KPYQWGFQ.js +0 -183
- package/dist/types-D05dCGma.d.ts +0 -521
- package/scripts/eslint-audit.cjs +0 -222
- package/scripts/generate-docs.js +0 -157
- package/scripts/install-cursor-rules.cjs +0 -255
- package/scripts/install-eslint-config.cjs +0 -349
- package/scripts/setup-build-cache.js +0 -73
- package/scripts/validate-pre-publish.js +0 -145
- package/src/__tests__/integration/UserProfile.test.tsx +0 -124
- package/src/__tests__/public-recipe-view.test.ts +0 -228
- package/src/__tests__/rls-policies.test.ts +0 -472
- package/src/components/DataTable/__tests__/DataTable.test.tsx +0 -876
- package/src/components/DataTable/components/DataTableLayout.tsx +0 -584
- package/src/components/DataTable/components/UnifiedTableBody.tsx +0 -395
- package/src/components/DataTable/components/__tests__/DataTableLayout.test.tsx +0 -467
- package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +0 -358
- package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +0 -957
- package/src/components/DataTable/core/ActionManager.ts +0 -235
- package/src/components/DataTable/core/ColumnManager.ts +0 -204
- package/src/components/DataTable/core/DataManager.ts +0 -190
- package/src/components/DataTable/core/LocalDataAdapter.ts +0 -274
- package/src/components/DataTable/core/PluginRegistry.ts +0 -229
- package/src/components/DataTable/core/StateManager.ts +0 -312
- package/src/components/DataTable/core/__tests__/ActionManager.test.ts +0 -235
- package/src/components/DataTable/core/__tests__/ColumnManager.test.ts +0 -141
- package/src/components/DataTable/core/__tests__/DataManager.test.ts +0 -178
- package/src/components/DataTable/core/__tests__/LocalDataAdapter.test.ts +0 -133
- package/src/components/DataTable/core/__tests__/PluginRegistry.test.ts +0 -142
- package/src/components/DataTable/core/__tests__/StateManager.test.ts +0 -158
- package/src/components/DataTable/core/interfaces.ts +0 -338
- package/src/components/DataTable/types.ts +0 -764
- package/src/hooks/public/usePublicFileDisplay.ts +0 -534
- package/src/hooks/useFileDisplay.ts +0 -748
- package/src/providers/OrganisationProvider.test.tsx +0 -40
- package/src/providers/OrganisationProvider.tsx +0 -92
- package/src/providers/__tests__/InactivityProvider.test-helper.tsx +0 -65
- package/src/providers/__tests__/OrganisationProvider.test.tsx +0 -616
- package/src/providers/__tests__/OrganisationProvider.wrapper.test.tsx +0 -591
- package/src/rbac/__tests__/cache-invalidation.test.ts +0 -393
- /package/src/components/DataTable/{components/__tests__ → ui}/COVERAGE_NOTE.md +0 -0
- /package/src/components/DataTable/utils/{__tests__/COVERAGE_NOTE.md → COVERAGE_NOTE.md} +0 -0
- /package/src/hooks/{__tests__/useApiFetch.unit.test.ts → useApiFetch.unit.test.ts} +0 -0
- /package/src/providers/{__tests__/README.md → README.md} +0 -0
- /package/src/rbac/{__tests__/index.test.ts → index.test.ts} +0 -0
- /package/src/rbac/{__tests__/rbac-integration.test.ts → rbac-integration.test.ts} +0 -0
- /package/src/types/{__tests__/README.md → README.md} +0 -0
|
@@ -76,14 +76,15 @@ describe('App ID Resolver', () => {
|
|
|
76
76
|
|
|
77
77
|
const result = await getAppId(mockSupabase as any, 'MY_APP');
|
|
78
78
|
|
|
79
|
-
expect(result).toBe(
|
|
79
|
+
expect(result.ok).toBe(true);
|
|
80
|
+
expect(result.data).toBe('app-123');
|
|
80
81
|
expect(mockSupabase.from).toHaveBeenCalledWith('rbac_apps');
|
|
81
82
|
expect(mockQueryBuilder.select).toHaveBeenCalledWith('id');
|
|
82
83
|
expect(mockQueryBuilder.ilike).toHaveBeenCalledWith('name', 'MY_APP');
|
|
83
84
|
expect(mockQueryBuilder.eq).toHaveBeenCalledWith('is_active', true);
|
|
84
85
|
}, TEST_TIMEOUT);
|
|
85
86
|
|
|
86
|
-
it('returns
|
|
87
|
+
it('returns err when app not found', async () => {
|
|
87
88
|
mockQueryBuilder.single.mockResolvedValue({
|
|
88
89
|
data: null,
|
|
89
90
|
error: { message: 'No rows found' }
|
|
@@ -91,7 +92,8 @@ describe('App ID Resolver', () => {
|
|
|
91
92
|
|
|
92
93
|
const result = await getAppId(mockSupabase as any, 'NONEXISTENT_APP');
|
|
93
94
|
|
|
94
|
-
expect(result).
|
|
95
|
+
expect(result.ok).toBe(false);
|
|
96
|
+
expect(result.error.message).toBe('No rows found');
|
|
95
97
|
}, TEST_TIMEOUT);
|
|
96
98
|
|
|
97
99
|
it('handles database errors gracefully', async () => {
|
|
@@ -102,7 +104,8 @@ describe('App ID Resolver', () => {
|
|
|
102
104
|
|
|
103
105
|
const result = await getAppId(mockSupabase as any, 'MY_APP');
|
|
104
106
|
|
|
105
|
-
expect(result).
|
|
107
|
+
expect(result.ok).toBe(false);
|
|
108
|
+
expect(result.error.message).toBe('Database error');
|
|
106
109
|
const logger = getMockLogger();
|
|
107
110
|
expect(vi.mocked(logger.error)).toHaveBeenCalledWith(
|
|
108
111
|
'Failed to resolve app ID for app name:',
|
|
@@ -116,7 +119,8 @@ describe('App ID Resolver', () => {
|
|
|
116
119
|
|
|
117
120
|
const result = await getAppId(mockSupabase as any, 'MY_APP');
|
|
118
121
|
|
|
119
|
-
expect(result).
|
|
122
|
+
expect(result.ok).toBe(false);
|
|
123
|
+
expect(result.error.message).toContain('Network error');
|
|
120
124
|
const logger = getMockLogger();
|
|
121
125
|
expect(vi.mocked(logger.error)).toHaveBeenCalledWith(
|
|
122
126
|
'Error resolving app ID for app name:',
|
|
@@ -129,14 +133,17 @@ describe('App ID Resolver', () => {
|
|
|
129
133
|
const result1 = await getAppId(mockSupabase as any, null as any);
|
|
130
134
|
const result2 = await getAppId(mockSupabase as any, undefined as any);
|
|
131
135
|
|
|
132
|
-
expect(result1).
|
|
133
|
-
expect(
|
|
136
|
+
expect(result1.ok).toBe(true);
|
|
137
|
+
expect(result1.data).toBeNull();
|
|
138
|
+
expect(result2.ok).toBe(true);
|
|
139
|
+
expect(result2.data).toBeNull();
|
|
134
140
|
});
|
|
135
141
|
|
|
136
142
|
it('handles empty app name', async () => {
|
|
137
143
|
const result = await getAppId(mockSupabase as any, '');
|
|
138
144
|
|
|
139
|
-
expect(result).
|
|
145
|
+
expect(result.ok).toBe(true);
|
|
146
|
+
expect(result.data).toBeNull();
|
|
140
147
|
}, TEST_TIMEOUT);
|
|
141
148
|
});
|
|
142
149
|
|
|
@@ -157,7 +164,8 @@ describe('App ID Resolver', () => {
|
|
|
157
164
|
|
|
158
165
|
const result = await getAppIds(mockSupabase as any, ['MY_APP']);
|
|
159
166
|
|
|
160
|
-
expect(result).
|
|
167
|
+
expect(result.ok).toBe(true);
|
|
168
|
+
expect(result.data).toEqual({ 'MY_APP': 'app-123' });
|
|
161
169
|
}, TEST_TIMEOUT);
|
|
162
170
|
|
|
163
171
|
it('resolves multiple app IDs', async () => {
|
|
@@ -180,7 +188,8 @@ describe('App ID Resolver', () => {
|
|
|
180
188
|
|
|
181
189
|
const result = await getAppIds(mockSupabase as any, ['MY_APP', 'ANOTHER_APP', 'MISSING_APP']);
|
|
182
190
|
|
|
183
|
-
expect(result).
|
|
191
|
+
expect(result.ok).toBe(true);
|
|
192
|
+
expect(result.data).toEqual({
|
|
184
193
|
'MY_APP': 'app-123',
|
|
185
194
|
'ANOTHER_APP': 'app-456',
|
|
186
195
|
'MISSING_APP': null
|
|
@@ -207,16 +216,18 @@ describe('App ID Resolver', () => {
|
|
|
207
216
|
|
|
208
217
|
const result = await getAppIds(mockSupabase as any, ['MY_APP', 'ANOTHER_APP']);
|
|
209
218
|
|
|
210
|
-
expect(result).
|
|
219
|
+
expect(result.ok).toBe(true);
|
|
220
|
+
expect(result.data).toEqual({
|
|
211
221
|
'MY_APP': 'app-123',
|
|
212
222
|
'ANOTHER_APP': 'app-456'
|
|
213
223
|
});
|
|
214
224
|
});
|
|
215
225
|
|
|
216
|
-
it('returns empty object for empty app names array', async () => {
|
|
226
|
+
it('returns ok with empty object for empty app names array', async () => {
|
|
217
227
|
const result = await getAppIds(mockSupabase as any, []);
|
|
218
228
|
|
|
219
|
-
expect(result).
|
|
229
|
+
expect(result.ok).toBe(true);
|
|
230
|
+
expect(result.data).toEqual({});
|
|
220
231
|
});
|
|
221
232
|
|
|
222
233
|
it('handles database errors gracefully', async () => {
|
|
@@ -235,7 +246,8 @@ describe('App ID Resolver', () => {
|
|
|
235
246
|
|
|
236
247
|
const result = await getAppIds(mockSupabase as any, ['MY_APP', 'ANOTHER_APP']);
|
|
237
248
|
|
|
238
|
-
expect(result).
|
|
249
|
+
expect(result.ok).toBe(false);
|
|
250
|
+
expect(result.error.message).toBe('Database error');
|
|
239
251
|
const logger = getMockLogger();
|
|
240
252
|
expect(vi.mocked(logger.error)).toHaveBeenCalledWith(
|
|
241
253
|
'Failed to resolve app IDs for app names:',
|
|
@@ -257,7 +269,8 @@ describe('App ID Resolver', () => {
|
|
|
257
269
|
|
|
258
270
|
const result = await getAppIds(mockSupabase as any, ['MY_APP', 'ANOTHER_APP']);
|
|
259
271
|
|
|
260
|
-
expect(result).
|
|
272
|
+
expect(result.ok).toBe(false);
|
|
273
|
+
expect(result.error.message).toContain('Network error');
|
|
261
274
|
const logger = getMockLogger();
|
|
262
275
|
expect(vi.mocked(logger.error)).toHaveBeenCalledWith(
|
|
263
276
|
'Error resolving app IDs for app names:',
|
|
@@ -270,8 +283,8 @@ describe('App ID Resolver', () => {
|
|
|
270
283
|
const result1 = await getAppIds(mockSupabase as any, null as any);
|
|
271
284
|
const result2 = await getAppIds(mockSupabase as any, undefined as any);
|
|
272
285
|
|
|
273
|
-
expect(result1).
|
|
274
|
-
expect(result2).
|
|
286
|
+
expect(result1.ok).toBe(false);
|
|
287
|
+
expect(result2.ok).toBe(false);
|
|
275
288
|
}, TEST_TIMEOUT);
|
|
276
289
|
|
|
277
290
|
it('handles duplicate app names in array', async () => {
|
|
@@ -290,11 +303,11 @@ describe('App ID Resolver', () => {
|
|
|
290
303
|
|
|
291
304
|
const result = await getAppIds(mockSupabase as any, ['MY_APP', 'MY_APP', 'MY_APP']);
|
|
292
305
|
|
|
293
|
-
expect(result).
|
|
306
|
+
expect(result.ok).toBe(true);
|
|
307
|
+
expect(result.data).toEqual({
|
|
294
308
|
'MY_APP': 'app-123'
|
|
295
309
|
});
|
|
296
|
-
|
|
297
|
-
expect(result['MY_APP']).toBe('app-123');
|
|
310
|
+
expect(result.data!['MY_APP']).toBe('app-123');
|
|
298
311
|
}, TEST_TIMEOUT);
|
|
299
312
|
|
|
300
313
|
it('handles app names with different cases correctly', async () => {
|
|
@@ -316,8 +329,9 @@ describe('App ID Resolver', () => {
|
|
|
316
329
|
|
|
317
330
|
const result = await getAppIds(mockSupabase as any, ['MY_APP', 'another_app']);
|
|
318
331
|
|
|
319
|
-
expect(result
|
|
320
|
-
expect(result['
|
|
332
|
+
expect(result.ok).toBe(true);
|
|
333
|
+
expect(result.data!['MY_APP']).toBe('app-123');
|
|
334
|
+
expect(result.data!['another_app']).toBe('app-456');
|
|
321
335
|
}, TEST_TIMEOUT);
|
|
322
336
|
});
|
|
323
337
|
|
|
@@ -337,9 +351,11 @@ describe('App ID Resolver', () => {
|
|
|
337
351
|
const result1 = await resolver.getAppId(mockSupabase as any, 'MY_APP');
|
|
338
352
|
const result2 = await resolver.getAppId(mockSupabase as any, 'MY_APP');
|
|
339
353
|
|
|
340
|
-
expect(result1).toBe(
|
|
341
|
-
expect(
|
|
342
|
-
expect(
|
|
354
|
+
expect(result1.ok).toBe(true);
|
|
355
|
+
expect(result1.data).toBe('app-123');
|
|
356
|
+
expect(result2.ok).toBe(true);
|
|
357
|
+
expect(result2.data).toBe('app-123');
|
|
358
|
+
expect(mockQueryBuilder.single).toHaveBeenCalledTimes(1);
|
|
343
359
|
}, TEST_TIMEOUT);
|
|
344
360
|
|
|
345
361
|
it('expires cached results after TTL', async () => {
|
|
@@ -351,14 +367,15 @@ describe('App ID Resolver', () => {
|
|
|
351
367
|
});
|
|
352
368
|
|
|
353
369
|
const result1 = await resolver.getAppId(mockSupabase as any, 'MY_APP');
|
|
354
|
-
expect(result1).toBe(
|
|
370
|
+
expect(result1.ok).toBe(true);
|
|
371
|
+
expect(result1.data).toBe('app-123');
|
|
355
372
|
|
|
356
|
-
// Clear cache to simulate TTL expiration
|
|
357
373
|
resolver.clearCacheForApp('MY_APP');
|
|
358
374
|
|
|
359
375
|
const result2 = await resolver.getAppId(mockSupabase as any, 'MY_APP');
|
|
360
|
-
expect(result2).toBe(
|
|
361
|
-
expect(
|
|
376
|
+
expect(result2.ok).toBe(true);
|
|
377
|
+
expect(result2.data).toBe('app-123');
|
|
378
|
+
expect(mockQueryBuilder.single).toHaveBeenCalledTimes(2);
|
|
362
379
|
});
|
|
363
380
|
|
|
364
381
|
it('handles cache misses gracefully', async () => {
|
|
@@ -369,7 +386,8 @@ describe('App ID Resolver', () => {
|
|
|
369
386
|
|
|
370
387
|
const result = await resolver.getAppId(mockSupabase as any, 'NONEXISTENT_APP');
|
|
371
388
|
|
|
372
|
-
expect(result).
|
|
389
|
+
expect(result.ok).toBe(false);
|
|
390
|
+
expect(result.error.message).toBe('No rows found');
|
|
373
391
|
}, TEST_TIMEOUT);
|
|
374
392
|
|
|
375
393
|
it('handles database errors gracefully', async () => {
|
|
@@ -380,7 +398,8 @@ describe('App ID Resolver', () => {
|
|
|
380
398
|
|
|
381
399
|
const result = await resolver.getAppId(mockSupabase as any, 'MY_APP');
|
|
382
400
|
|
|
383
|
-
expect(result).
|
|
401
|
+
expect(result.ok).toBe(false);
|
|
402
|
+
expect(result.error.message).toBe('Database error');
|
|
384
403
|
const logger = getMockLogger();
|
|
385
404
|
expect(vi.mocked(logger.error)).toHaveBeenCalledWith(
|
|
386
405
|
'Failed to resolve app ID for app name:',
|
|
@@ -395,12 +414,12 @@ describe('App ID Resolver', () => {
|
|
|
395
414
|
.mockResolvedValueOnce({ data: { id: 'app-123' }, error: null });
|
|
396
415
|
|
|
397
416
|
const result1 = await resolver.getAppId(mockSupabase as any, 'MY_APP');
|
|
398
|
-
expect(result1).
|
|
417
|
+
expect(result1.ok).toBe(false);
|
|
399
418
|
|
|
400
|
-
// Clear cache and try again - should succeed this time
|
|
401
419
|
resolver.clearCacheForApp('MY_APP');
|
|
402
420
|
const result2 = await resolver.getAppId(mockSupabase as any, 'MY_APP');
|
|
403
|
-
expect(result2).toBe(
|
|
421
|
+
expect(result2.ok).toBe(true);
|
|
422
|
+
expect(result2.data).toBe('app-123');
|
|
404
423
|
}, TEST_TIMEOUT);
|
|
405
424
|
|
|
406
425
|
it('clears cache correctly', async () => {
|
|
@@ -414,8 +433,9 @@ describe('App ID Resolver', () => {
|
|
|
414
433
|
|
|
415
434
|
const result = await resolver.getAppId(mockSupabase as any, 'MY_APP');
|
|
416
435
|
|
|
417
|
-
expect(result).toBe(
|
|
418
|
-
expect(
|
|
436
|
+
expect(result.ok).toBe(true);
|
|
437
|
+
expect(result.data).toBe('app-123');
|
|
438
|
+
expect(mockQueryBuilder.single).toHaveBeenCalledTimes(2);
|
|
419
439
|
});
|
|
420
440
|
|
|
421
441
|
it('handles multiple apps with different cache states', async () => {
|
|
@@ -428,27 +448,30 @@ describe('App ID Resolver', () => {
|
|
|
428
448
|
const result2 = await resolver.getAppId(mockSupabase as any, 'APP2');
|
|
429
449
|
const result3 = await resolver.getAppId(mockSupabase as any, 'APP3');
|
|
430
450
|
|
|
431
|
-
expect(result1).toBe(
|
|
432
|
-
expect(
|
|
433
|
-
expect(
|
|
451
|
+
expect(result1.ok).toBe(true);
|
|
452
|
+
expect(result1.data).toBe('app-1');
|
|
453
|
+
expect(result2.ok).toBe(true);
|
|
454
|
+
expect(result2.data).toBe('app-2');
|
|
455
|
+
expect(result3.ok).toBe(true);
|
|
456
|
+
expect(result3.data).toBe('app-3');
|
|
434
457
|
expect(mockQueryBuilder.single).toHaveBeenCalledTimes(3);
|
|
435
458
|
|
|
436
|
-
// Second calls should use cache
|
|
437
459
|
const cached1 = await resolver.getAppId(mockSupabase as any, 'APP1');
|
|
438
460
|
const cached2 = await resolver.getAppId(mockSupabase as any, 'APP2');
|
|
439
461
|
const cached3 = await resolver.getAppId(mockSupabase as any, 'APP3');
|
|
440
462
|
|
|
441
|
-
expect(cached1).toBe(
|
|
442
|
-
expect(
|
|
443
|
-
expect(
|
|
444
|
-
expect(
|
|
463
|
+
expect(cached1.ok).toBe(true);
|
|
464
|
+
expect(cached1.data).toBe('app-1');
|
|
465
|
+
expect(cached2.ok).toBe(true);
|
|
466
|
+
expect(cached2.data).toBe('app-2');
|
|
467
|
+
expect(cached3.ok).toBe(true);
|
|
468
|
+
expect(cached3.data).toBe('app-3');
|
|
469
|
+
expect(mockQueryBuilder.single).toHaveBeenCalledTimes(3);
|
|
445
470
|
}, TEST_TIMEOUT);
|
|
446
471
|
|
|
447
472
|
it('handles cache expiration with TTL', async () => {
|
|
448
|
-
// Create resolver with short TTL for testing
|
|
449
473
|
const shortTTLResolver = new CachedAppIdResolver();
|
|
450
|
-
|
|
451
|
-
(shortTTLResolver as any).ttl = 100; // 100ms TTL
|
|
474
|
+
(shortTTLResolver as any).ttl = 100;
|
|
452
475
|
|
|
453
476
|
mockQueryBuilder.single.mockResolvedValue({
|
|
454
477
|
data: { id: 'app-123' },
|
|
@@ -456,22 +479,23 @@ describe('App ID Resolver', () => {
|
|
|
456
479
|
});
|
|
457
480
|
|
|
458
481
|
const result1 = await shortTTLResolver.getAppId(mockSupabase as any, 'MY_APP');
|
|
459
|
-
expect(result1).toBe(
|
|
482
|
+
expect(result1.ok).toBe(true);
|
|
483
|
+
expect(result1.data).toBe('app-123');
|
|
460
484
|
expect(mockQueryBuilder.single).toHaveBeenCalledTimes(1);
|
|
461
485
|
|
|
462
|
-
// Wait for TTL to expire
|
|
463
486
|
await new Promise(resolve => setTimeout(resolve, 150));
|
|
464
487
|
|
|
465
488
|
const result2 = await shortTTLResolver.getAppId(mockSupabase as any, 'MY_APP');
|
|
466
|
-
expect(result2).toBe(
|
|
467
|
-
expect(
|
|
489
|
+
expect(result2.ok).toBe(true);
|
|
490
|
+
expect(result2.data).toBe('app-123');
|
|
491
|
+
expect(mockQueryBuilder.single).toHaveBeenCalledTimes(2);
|
|
468
492
|
}, TEST_TIMEOUT);
|
|
469
493
|
|
|
470
494
|
it('clears cache for specific app while keeping others', async () => {
|
|
471
495
|
mockQueryBuilder.single
|
|
472
496
|
.mockResolvedValueOnce({ data: { id: 'app-1' }, error: null })
|
|
473
497
|
.mockResolvedValueOnce({ data: { id: 'app-2' }, error: null })
|
|
474
|
-
.mockResolvedValueOnce({ data: { id: 'app-1' }, error: null });
|
|
498
|
+
.mockResolvedValueOnce({ data: { id: 'app-1' }, error: null });
|
|
475
499
|
|
|
476
500
|
await resolver.getAppId(mockSupabase as any, 'APP1');
|
|
477
501
|
await resolver.getAppId(mockSupabase as any, 'APP2');
|
|
@@ -480,31 +504,30 @@ describe('App ID Resolver', () => {
|
|
|
480
504
|
|
|
481
505
|
resolver.clearCacheForApp('APP1');
|
|
482
506
|
|
|
483
|
-
// APP1 should be re-fetched, APP2 should still be cached
|
|
484
507
|
await resolver.getAppId(mockSupabase as any, 'APP1');
|
|
485
508
|
await resolver.getAppId(mockSupabase as any, 'APP2');
|
|
486
509
|
|
|
487
|
-
expect(mockQueryBuilder.single).toHaveBeenCalledTimes(3);
|
|
510
|
+
expect(mockQueryBuilder.single).toHaveBeenCalledTimes(3);
|
|
488
511
|
}, TEST_TIMEOUT);
|
|
489
512
|
|
|
490
513
|
it('handles clearing cache for non-existent app', () => {
|
|
491
514
|
expect(() => resolver.clearCacheForApp('NONEXISTENT')).not.toThrow();
|
|
492
515
|
}, TEST_TIMEOUT);
|
|
493
516
|
|
|
494
|
-
it('
|
|
517
|
+
it('does not cache error results', async () => {
|
|
495
518
|
mockQueryBuilder.single.mockResolvedValue({
|
|
496
519
|
data: null,
|
|
497
520
|
error: { message: 'Not found' }
|
|
498
521
|
});
|
|
499
522
|
|
|
500
523
|
const result1 = await resolver.getAppId(mockSupabase as any, 'MISSING_APP');
|
|
501
|
-
expect(result1).
|
|
524
|
+
expect(result1.ok).toBe(false);
|
|
525
|
+
expect(result1.error.message).toBe('Not found');
|
|
502
526
|
expect(mockQueryBuilder.single).toHaveBeenCalledTimes(1);
|
|
503
527
|
|
|
504
|
-
// Should use cached null result
|
|
505
528
|
const result2 = await resolver.getAppId(mockSupabase as any, 'MISSING_APP');
|
|
506
|
-
expect(result2).
|
|
507
|
-
expect(mockQueryBuilder.single).toHaveBeenCalledTimes(
|
|
529
|
+
expect(result2.ok).toBe(false);
|
|
530
|
+
expect(mockQueryBuilder.single).toHaveBeenCalledTimes(2);
|
|
508
531
|
}, TEST_TIMEOUT);
|
|
509
532
|
|
|
510
533
|
it('handles singleton instance correctly', async () => {
|
|
@@ -516,7 +539,8 @@ describe('App ID Resolver', () => {
|
|
|
516
539
|
});
|
|
517
540
|
|
|
518
541
|
const result = await cachedAppIdResolver.getAppId(mockSupabase as any, 'MY_APP');
|
|
519
|
-
expect(result).toBe(
|
|
542
|
+
expect(result.ok).toBe(true);
|
|
543
|
+
expect(result.data).toBe('app-123');
|
|
520
544
|
}, TEST_TIMEOUT);
|
|
521
545
|
});
|
|
522
546
|
|
|
@@ -536,7 +560,8 @@ describe('App ID Resolver', () => {
|
|
|
536
560
|
|
|
537
561
|
const result = await getAppId(mockClient as any, 'MY_APP');
|
|
538
562
|
|
|
539
|
-
expect(result).toBe(
|
|
563
|
+
expect(result.ok).toBe(true);
|
|
564
|
+
expect(result.data).toBe('app-123');
|
|
540
565
|
expect(mockClient.from).toHaveBeenCalledWith('rbac_apps');
|
|
541
566
|
});
|
|
542
567
|
|
|
@@ -567,7 +592,8 @@ describe('App ID Resolver', () => {
|
|
|
567
592
|
|
|
568
593
|
const result = await getAppIds(mockSupabase as any, appNames);
|
|
569
594
|
|
|
570
|
-
expect(result).
|
|
595
|
+
expect(result.ok).toBe(true);
|
|
596
|
+
expect(result.data).toEqual({
|
|
571
597
|
'MY_APP': 'app-123',
|
|
572
598
|
'my-app': 'app-456',
|
|
573
599
|
'my_app': null,
|
|
@@ -583,7 +609,8 @@ describe('App ID Resolver', () => {
|
|
|
583
609
|
|
|
584
610
|
const result = await getAppId(mockSupabase as any, 'MY_APP');
|
|
585
611
|
|
|
586
|
-
expect(result).
|
|
612
|
+
expect(result.ok).toBe(false);
|
|
613
|
+
expect(result.error.message).toContain('Request timeout');
|
|
587
614
|
const logger = getMockLogger();
|
|
588
615
|
expect(vi.mocked(logger.error)).toHaveBeenCalledWith(
|
|
589
616
|
'Error resolving app ID for app name:',
|
|
@@ -600,7 +627,8 @@ describe('App ID Resolver', () => {
|
|
|
600
627
|
|
|
601
628
|
const result = await getAppId(mockSupabase as any, 'MY_APP');
|
|
602
629
|
|
|
603
|
-
expect(result).
|
|
630
|
+
expect(result.ok).toBe(true);
|
|
631
|
+
expect(result.data).toBeNull();
|
|
604
632
|
}, TEST_TIMEOUT);
|
|
605
633
|
|
|
606
634
|
it('handles null data responses', async () => {
|
|
@@ -611,7 +639,8 @@ describe('App ID Resolver', () => {
|
|
|
611
639
|
|
|
612
640
|
const result = await getAppId(mockSupabase as any, 'MY_APP');
|
|
613
641
|
|
|
614
|
-
expect(result).
|
|
642
|
+
expect(result.ok).toBe(true);
|
|
643
|
+
expect(result.data).toBeNull();
|
|
615
644
|
}, TEST_TIMEOUT);
|
|
616
645
|
});
|
|
617
646
|
|
|
@@ -636,8 +665,9 @@ describe('App ID Resolver', () => {
|
|
|
636
665
|
const result = await getAppIds(mockSupabase as any, appNames);
|
|
637
666
|
const endTime = Date.now();
|
|
638
667
|
|
|
639
|
-
expect(
|
|
640
|
-
expect(
|
|
668
|
+
expect(result.ok).toBe(true);
|
|
669
|
+
expect(Object.keys(result.data!)).toHaveLength(100);
|
|
670
|
+
expect(endTime - startTime).toBeLessThan(1000);
|
|
641
671
|
});
|
|
642
672
|
|
|
643
673
|
it('caches results efficiently', async () => {
|
|
@@ -650,16 +680,13 @@ describe('App ID Resolver', () => {
|
|
|
650
680
|
|
|
651
681
|
const startTime = Date.now();
|
|
652
682
|
|
|
653
|
-
// First call - should hit database
|
|
654
683
|
await resolver.getAppId(mockSupabase as any, 'MY_APP');
|
|
655
|
-
|
|
656
|
-
// Second call - should hit cache
|
|
657
684
|
await resolver.getAppId(mockSupabase as any, 'MY_APP');
|
|
658
685
|
|
|
659
686
|
const endTime = Date.now();
|
|
660
687
|
|
|
661
688
|
expect(mockQueryBuilder.single).toHaveBeenCalledTimes(1);
|
|
662
|
-
expect(endTime - startTime).toBeLessThan(100);
|
|
689
|
+
expect(endTime - startTime).toBeLessThan(100);
|
|
663
690
|
}, TEST_TIMEOUT);
|
|
664
691
|
});
|
|
665
692
|
});
|
|
@@ -9,21 +9,30 @@
|
|
|
9
9
|
|
|
10
10
|
import type { SupabaseClient } from '@supabase/supabase-js';
|
|
11
11
|
import type { Database } from '../../types/database';
|
|
12
|
+
import { ok, err, type ApiResult, type ApiError } from '../../types/api-result';
|
|
12
13
|
import { createLogger } from '../core/logger';
|
|
13
14
|
|
|
14
15
|
const log = createLogger('AppIdResolver');
|
|
15
16
|
|
|
17
|
+
function toApiError(error: unknown): ApiError {
|
|
18
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
19
|
+
const code = error instanceof Error && (error as Error & { code?: string }).code
|
|
20
|
+
? (error as Error & { code: string }).code
|
|
21
|
+
: 'APP_ID_RESOLVER_ERROR';
|
|
22
|
+
return { code, message };
|
|
23
|
+
}
|
|
24
|
+
|
|
16
25
|
/**
|
|
17
26
|
* Resolves an app name to its corresponding app ID
|
|
18
27
|
*
|
|
19
28
|
* @param supabase - Supabase client instance
|
|
20
29
|
* @param appName - The app name to resolve
|
|
21
|
-
* @returns Promise resolving to
|
|
30
|
+
* @returns Promise resolving to ApiResult with app ID or null if not found
|
|
22
31
|
*/
|
|
23
32
|
export async function getAppId(
|
|
24
33
|
supabase: SupabaseClient<Database>,
|
|
25
34
|
appName: string
|
|
26
|
-
): Promise<string | null
|
|
35
|
+
): Promise<ApiResult<string | null>> {
|
|
27
36
|
try {
|
|
28
37
|
const { data, error } = await supabase
|
|
29
38
|
.from('rbac_apps')
|
|
@@ -34,13 +43,13 @@ export async function getAppId(
|
|
|
34
43
|
|
|
35
44
|
if (error) {
|
|
36
45
|
log.error('Failed to resolve app ID for app name:', appName, error);
|
|
37
|
-
return
|
|
46
|
+
return err({ code: 'APP_ID_RESOLVE_ERROR', message: error.message });
|
|
38
47
|
}
|
|
39
48
|
|
|
40
|
-
return (data as { id: string } | null)?.id
|
|
41
|
-
} catch (
|
|
42
|
-
log.error('Error resolving app ID for app name:', appName,
|
|
43
|
-
return
|
|
49
|
+
return ok((data as { id: string } | null)?.id ?? null);
|
|
50
|
+
} catch (e) {
|
|
51
|
+
log.error('Error resolving app ID for app name:', appName, e);
|
|
52
|
+
return err(toApiError(e));
|
|
44
53
|
}
|
|
45
54
|
}
|
|
46
55
|
|
|
@@ -49,12 +58,12 @@ export async function getAppId(
|
|
|
49
58
|
*
|
|
50
59
|
* @param supabase - Supabase client instance
|
|
51
60
|
* @param appNames - Array of app names to resolve
|
|
52
|
-
* @returns Promise resolving to
|
|
61
|
+
* @returns Promise resolving to ApiResult with map of app names to app IDs
|
|
53
62
|
*/
|
|
54
63
|
export async function getAppIds(
|
|
55
64
|
supabase: SupabaseClient<Database>,
|
|
56
65
|
appNames: string[]
|
|
57
|
-
): Promise<Record<string, string | null
|
|
66
|
+
): Promise<ApiResult<Record<string, string | null>>> {
|
|
58
67
|
try {
|
|
59
68
|
// For case-insensitive matching with multiple values, we need to use OR conditions
|
|
60
69
|
// since PostgreSQL doesn't support case-insensitive IN with ILIKE
|
|
@@ -68,7 +77,7 @@ export async function getAppIds(
|
|
|
68
77
|
|
|
69
78
|
if (error) {
|
|
70
79
|
log.error('Failed to resolve app IDs for app names:', appNames, error);
|
|
71
|
-
return {};
|
|
80
|
+
return err({ code: 'APP_IDS_RESOLVE_ERROR', message: error.message });
|
|
72
81
|
}
|
|
73
82
|
|
|
74
83
|
const result: Record<string, string | null> = {};
|
|
@@ -89,10 +98,10 @@ export async function getAppIds(
|
|
|
89
98
|
}
|
|
90
99
|
});
|
|
91
100
|
|
|
92
|
-
return result;
|
|
93
|
-
} catch (
|
|
94
|
-
log.error('Error resolving app IDs for app names:', appNames,
|
|
95
|
-
return
|
|
101
|
+
return ok(result);
|
|
102
|
+
} catch (e) {
|
|
103
|
+
log.error('Error resolving app IDs for app names:', appNames, e);
|
|
104
|
+
return err(toApiError(e));
|
|
96
105
|
}
|
|
97
106
|
}
|
|
98
107
|
|
|
@@ -106,18 +115,20 @@ export class CachedAppIdResolver {
|
|
|
106
115
|
async getAppId(
|
|
107
116
|
supabase: SupabaseClient<Database>,
|
|
108
117
|
appName: string
|
|
109
|
-
): Promise<string | null
|
|
118
|
+
): Promise<ApiResult<string | null>> {
|
|
110
119
|
const now = Date.now();
|
|
111
120
|
const cached = this.cache.get(appName);
|
|
112
121
|
|
|
113
122
|
if (cached && cached.expires > now) {
|
|
114
|
-
return cached.id;
|
|
123
|
+
return ok(cached.id);
|
|
115
124
|
}
|
|
116
125
|
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
126
|
+
const result = await getAppId(supabase, appName);
|
|
127
|
+
if (!result.ok) {
|
|
128
|
+
return result;
|
|
129
|
+
}
|
|
130
|
+
this.cache.set(appName, { id: result.data, expires: now + this.ttl });
|
|
131
|
+
return ok(result.data);
|
|
121
132
|
}
|
|
122
133
|
|
|
123
134
|
clearCache(): void {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
2
|
-
import { setAppConfig, getAppConfig, getCurrentAppName, getCurrentAppId } from '
|
|
2
|
+
import { setAppConfig, getAppConfig, getCurrentAppName, getCurrentAppId } from './app/appConfig';
|
|
3
3
|
|
|
4
4
|
describe('App Configuration Utilities', () => {
|
|
5
5
|
beforeEach(() => {
|
|
@@ -5,47 +5,46 @@ import {
|
|
|
5
5
|
resetPassword,
|
|
6
6
|
updatePassword,
|
|
7
7
|
auditLogger
|
|
8
|
-
} from '
|
|
8
|
+
} from './security/auth-utils';
|
|
9
9
|
|
|
10
10
|
describe('Auth Utils', () => {
|
|
11
11
|
beforeEach(() => {
|
|
12
12
|
vi.restoreAllMocks();
|
|
13
13
|
});
|
|
14
14
|
|
|
15
|
-
it('signInWithEmail
|
|
15
|
+
it('signInWithEmail returns ApiResult error', async () => {
|
|
16
16
|
const result = await signInWithEmail({ email: 'test@example.com', password: 'pw' });
|
|
17
|
-
expect(result).
|
|
18
|
-
expect(result.error).
|
|
17
|
+
expect(result.ok).toBe(false);
|
|
18
|
+
expect(result.error).toMatchObject({ code: expect.any(String), message: expect.any(String) });
|
|
19
19
|
});
|
|
20
20
|
|
|
21
|
-
it('signUpWithEmail
|
|
21
|
+
it('signUpWithEmail returns ApiResult error', async () => {
|
|
22
22
|
const result = await signUpWithEmail({ email: 'new@example.com', password: 'pw' });
|
|
23
|
-
expect(result).
|
|
24
|
-
expect(result.error).
|
|
23
|
+
expect(result.ok).toBe(false);
|
|
24
|
+
expect(result.error).toMatchObject({ code: expect.any(String), message: expect.any(String) });
|
|
25
25
|
});
|
|
26
26
|
|
|
27
|
-
it('resetPassword
|
|
27
|
+
it('resetPassword returns ApiResult error', async () => {
|
|
28
28
|
const result = await resetPassword('reset@example.com');
|
|
29
|
-
expect(result).
|
|
30
|
-
expect(result.error).
|
|
29
|
+
expect(result.ok).toBe(false);
|
|
30
|
+
expect(result.error).toMatchObject({ code: expect.any(String), message: expect.any(String) });
|
|
31
31
|
});
|
|
32
32
|
|
|
33
|
-
it('updatePassword calls supabaseClient.auth.updateUser and returns
|
|
33
|
+
it('updatePassword calls supabaseClient.auth.updateUser and returns ok', async () => {
|
|
34
34
|
const updateUser = vi.fn().mockResolvedValue({ error: undefined });
|
|
35
35
|
const supabaseClient = { auth: { updateUser } } as any;
|
|
36
36
|
const result = await updatePassword(supabaseClient, 'newpw');
|
|
37
37
|
expect(updateUser).toHaveBeenCalledWith({ password: 'newpw' });
|
|
38
|
-
expect(result).
|
|
38
|
+
expect(result.ok).toBe(true);
|
|
39
|
+
expect(result.data).toBeUndefined();
|
|
39
40
|
});
|
|
40
41
|
|
|
41
|
-
it('updatePassword returns error if thrown', async () => {
|
|
42
|
+
it('updatePassword returns ApiResult error if thrown', async () => {
|
|
42
43
|
const updateUser = vi.fn().mockRejectedValue(new Error('fail'));
|
|
43
44
|
const supabaseClient = { auth: { updateUser } } as any;
|
|
44
45
|
const result = await updatePassword(supabaseClient, 'pw');
|
|
45
|
-
expect(result.
|
|
46
|
-
|
|
47
|
-
expect(result.error.message).toBe('fail');
|
|
48
|
-
}
|
|
46
|
+
expect(result.ok).toBe(false);
|
|
47
|
+
expect(result.error.message).toBe('fail');
|
|
49
48
|
});
|
|
50
49
|
|
|
51
50
|
it('auditLogger.log logs event', () => {
|