create-mithaq 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/LICENSES/payload.txt +22 -0
- package/LICENSES/ponytail.txt +21 -0
- package/index.js +127 -0
- package/package.json +19 -4
- package/template/apps/asas-platform/components.json +25 -0
- package/template/apps/asas-platform/gitignore +3 -0
- package/template/apps/asas-platform/package.json +55 -0
- package/template/apps/asas-platform/public/favicon.svg +1 -0
- package/template/apps/asas-platform/src/api.ts +147 -0
- package/template/apps/asas-platform/src/auth-frame.tsx +150 -0
- package/template/apps/asas-platform/src/components/mithaq/cells.tsx +112 -0
- package/template/apps/asas-platform/src/components/mithaq/controls.tsx +650 -0
- package/template/apps/asas-platform/src/components/mithaq/field-shell.tsx +53 -0
- package/template/apps/asas-platform/src/components/mithaq/filter-operators.ts +108 -0
- package/template/apps/asas-platform/src/components/mithaq/form.tsx +1467 -0
- package/template/apps/asas-platform/src/components/mithaq/list-columns.tsx +108 -0
- package/template/apps/asas-platform/src/components/mithaq/list-filters.tsx +368 -0
- package/template/apps/asas-platform/src/components/mithaq/list-pagination.tsx +153 -0
- package/template/apps/asas-platform/src/components/mithaq/list-query.ts +432 -0
- package/template/apps/asas-platform/src/components/mithaq/list-selection.tsx +74 -0
- package/template/apps/asas-platform/src/components/mithaq/list.tsx +865 -0
- package/template/apps/asas-platform/src/components/mithaq/nav.tsx +871 -0
- package/template/apps/asas-platform/src/components/mithaq/nodes.tsx +1024 -0
- package/template/apps/asas-platform/src/components/mithaq/relationship-cell.tsx +127 -0
- package/template/apps/asas-platform/src/components/mithaq/relationship-control.tsx +400 -0
- package/template/apps/asas-platform/src/components/mithaq/rich-text-nodes.ts +6 -0
- package/template/apps/asas-platform/src/components/mithaq/rich-text.tsx +1083 -0
- package/template/apps/asas-platform/src/components/mithaq/upload.tsx +686 -0
- package/template/apps/asas-platform/src/components/ui/accordion.tsx +74 -0
- package/template/apps/asas-platform/src/components/ui/alert-dialog.tsx +185 -0
- package/template/apps/asas-platform/src/components/ui/avatar.tsx +106 -0
- package/template/apps/asas-platform/src/components/ui/badge.tsx +48 -0
- package/template/apps/asas-platform/src/components/ui/breadcrumb.tsx +124 -0
- package/template/apps/asas-platform/src/components/ui/button-group.tsx +87 -0
- package/template/apps/asas-platform/src/components/ui/button.tsx +55 -0
- package/template/apps/asas-platform/src/components/ui/calendar.tsx +223 -0
- package/template/apps/asas-platform/src/components/ui/card.tsx +102 -0
- package/template/apps/asas-platform/src/components/ui/chart.tsx +371 -0
- package/template/apps/asas-platform/src/components/ui/checkbox.tsx +28 -0
- package/template/apps/asas-platform/src/components/ui/collapsible.tsx +19 -0
- package/template/apps/asas-platform/src/components/ui/combobox.tsx +308 -0
- package/template/apps/asas-platform/src/components/ui/dialog.tsx +158 -0
- package/template/apps/asas-platform/src/components/ui/direction.tsx +6 -0
- package/template/apps/asas-platform/src/components/ui/directional-icon.tsx +20 -0
- package/template/apps/asas-platform/src/components/ui/drawer.tsx +216 -0
- package/template/apps/asas-platform/src/components/ui/dropdown-menu.tsx +267 -0
- package/template/apps/asas-platform/src/components/ui/field.tsx +236 -0
- package/template/apps/asas-platform/src/components/ui/input-group.tsx +155 -0
- package/template/apps/asas-platform/src/components/ui/input-otp.tsx +84 -0
- package/template/apps/asas-platform/src/components/ui/input.tsx +19 -0
- package/template/apps/asas-platform/src/components/ui/label.tsx +19 -0
- package/template/apps/asas-platform/src/components/ui/popover.tsx +90 -0
- package/template/apps/asas-platform/src/components/ui/radio-group.tsx +37 -0
- package/template/apps/asas-platform/src/components/ui/resizable.tsx +47 -0
- package/template/apps/asas-platform/src/components/ui/scroll-area.tsx +54 -0
- package/template/apps/asas-platform/src/components/ui/select.tsx +204 -0
- package/template/apps/asas-platform/src/components/ui/separator.tsx +24 -0
- package/template/apps/asas-platform/src/components/ui/sheet.tsx +139 -0
- package/template/apps/asas-platform/src/components/ui/sidebar.tsx +714 -0
- package/template/apps/asas-platform/src/components/ui/skeleton.tsx +13 -0
- package/template/apps/asas-platform/src/components/ui/slider.tsx +55 -0
- package/template/apps/asas-platform/src/components/ui/spinner.tsx +10 -0
- package/template/apps/asas-platform/src/components/ui/switch.tsx +29 -0
- package/template/apps/asas-platform/src/components/ui/table.tsx +115 -0
- package/template/apps/asas-platform/src/components/ui/tabs.tsx +79 -0
- package/template/apps/asas-platform/src/components/ui/textarea.tsx +17 -0
- package/template/apps/asas-platform/src/components/ui/toggle-group.tsx +89 -0
- package/template/apps/asas-platform/src/components/ui/toggle.tsx +44 -0
- package/template/apps/asas-platform/src/components/ui/tooltip.tsx +63 -0
- package/template/apps/asas-platform/src/copy.ts +1 -0
- package/template/apps/asas-platform/src/hooks/use-mobile.ts +19 -0
- package/template/apps/asas-platform/src/lib/utils.ts +1 -0
- package/template/apps/asas-platform/src/links.ts +38 -0
- package/template/apps/asas-platform/src/locale-switch.tsx +26 -0
- package/template/apps/asas-platform/src/redirect.ts +1 -0
- package/template/apps/asas-platform/src/request-headers.ts +11 -0
- package/template/apps/asas-platform/src/routeTree.gen.ts +181 -0
- package/template/apps/asas-platform/src/router.tsx +7 -0
- package/template/apps/asas-platform/src/routes/(screens)/platform/files.ts +4 -0
- package/template/apps/asas-platform/src/routes/(screens)/platform/screen.json +3609 -0
- package/template/apps/asas-platform/src/routes/(screens)/platform/types.ts +145 -0
- package/template/apps/asas-platform/src/routes/(screens)/platform.$.tsx +17 -0
- package/template/apps/asas-platform/src/routes/(screens)/platform.index.tsx +10 -0
- package/template/apps/asas-platform/src/routes/(screens)/platform.tsx +13 -0
- package/template/apps/asas-platform/src/routes/__root.tsx +95 -0
- package/template/apps/asas-platform/src/routes/api/$.ts +30 -0
- package/template/apps/asas-platform/src/routes/auth.sign-in.tsx +72 -0
- package/template/apps/asas-platform/src/routes/unauthorized.tsx +122 -0
- package/template/apps/asas-platform/src/screen-form.tsx +34 -0
- package/template/apps/asas-platform/src/screen-list.tsx +139 -0
- package/template/apps/asas-platform/src/screen-names.ts +10 -0
- package/template/apps/asas-platform/src/screens.tsx +868 -0
- package/template/apps/asas-platform/src/server.ts +20 -0
- package/template/apps/asas-platform/src/slide.ts +22 -0
- package/template/apps/asas-platform/src/start.ts +42 -0
- package/template/apps/asas-platform/src/styles.css +200 -0
- package/template/apps/asas-platform/src/theme.ts +2 -0
- package/template/apps/asas-platform/tsconfig.json +19 -0
- package/template/apps/asas-platform/vite.config.ts +26 -0
- package/template/apps/asas-tanstack/components.json +25 -0
- package/template/apps/asas-tanstack/gitignore +3 -0
- package/template/apps/asas-tanstack/package.json +56 -0
- package/template/apps/asas-tanstack/public/favicon.svg +1 -0
- package/template/apps/asas-tanstack/src/api.ts +147 -0
- package/template/apps/asas-tanstack/src/auth-frame.tsx +150 -0
- package/template/apps/asas-tanstack/src/components/mithaq/cells.tsx +112 -0
- package/template/apps/asas-tanstack/src/components/mithaq/controls.tsx +650 -0
- package/template/apps/asas-tanstack/src/components/mithaq/field-shell.tsx +53 -0
- package/template/apps/asas-tanstack/src/components/mithaq/filter-operators.ts +108 -0
- package/template/apps/asas-tanstack/src/components/mithaq/form.tsx +1467 -0
- package/template/apps/asas-tanstack/src/components/mithaq/list-columns.tsx +108 -0
- package/template/apps/asas-tanstack/src/components/mithaq/list-filters.tsx +368 -0
- package/template/apps/asas-tanstack/src/components/mithaq/list-pagination.tsx +153 -0
- package/template/apps/asas-tanstack/src/components/mithaq/list-query.ts +432 -0
- package/template/apps/asas-tanstack/src/components/mithaq/list-selection.tsx +74 -0
- package/template/apps/asas-tanstack/src/components/mithaq/list.tsx +865 -0
- package/template/apps/asas-tanstack/src/components/mithaq/nav.tsx +871 -0
- package/template/apps/asas-tanstack/src/components/mithaq/nodes.tsx +1024 -0
- package/template/apps/asas-tanstack/src/components/mithaq/relationship-cell.tsx +127 -0
- package/template/apps/asas-tanstack/src/components/mithaq/relationship-control.tsx +400 -0
- package/template/apps/asas-tanstack/src/components/mithaq/rich-text-nodes.ts +6 -0
- package/template/apps/asas-tanstack/src/components/mithaq/rich-text.tsx +1083 -0
- package/template/apps/asas-tanstack/src/components/mithaq/upload.tsx +686 -0
- package/template/apps/asas-tanstack/src/components/ui/accordion.tsx +10 -0
- package/template/apps/asas-tanstack/src/components/ui/alert-dialog.tsx +173 -0
- package/template/apps/asas-tanstack/src/components/ui/avatar.tsx +104 -0
- package/template/apps/asas-tanstack/src/components/ui/badge.tsx +48 -0
- package/template/apps/asas-tanstack/src/components/ui/breadcrumb.tsx +125 -0
- package/template/apps/asas-tanstack/src/components/ui/button-group.tsx +87 -0
- package/template/apps/asas-tanstack/src/components/ui/button.tsx +56 -0
- package/template/apps/asas-tanstack/src/components/ui/calendar.tsx +223 -0
- package/template/apps/asas-tanstack/src/components/ui/card.tsx +94 -0
- package/template/apps/asas-tanstack/src/components/ui/chart.tsx +369 -0
- package/template/apps/asas-tanstack/src/components/ui/checkbox.tsx +27 -0
- package/template/apps/asas-tanstack/src/components/ui/collapsible.tsx +19 -0
- package/template/apps/asas-tanstack/src/components/ui/combobox.tsx +300 -0
- package/template/apps/asas-tanstack/src/components/ui/dialog.tsx +149 -0
- package/template/apps/asas-tanstack/src/components/ui/direction.tsx +5 -0
- package/template/apps/asas-tanstack/src/components/ui/directional-icon.tsx +20 -0
- package/template/apps/asas-tanstack/src/components/ui/drawer.tsx +215 -0
- package/template/apps/asas-tanstack/src/components/ui/dropdown-menu.tsx +267 -0
- package/template/apps/asas-tanstack/src/components/ui/field.tsx +225 -0
- package/template/apps/asas-tanstack/src/components/ui/input-group.tsx +147 -0
- package/template/apps/asas-tanstack/src/components/ui/input-otp.tsx +20 -0
- package/template/apps/asas-tanstack/src/components/ui/input.tsx +20 -0
- package/template/apps/asas-tanstack/src/components/ui/label.tsx +18 -0
- package/template/apps/asas-tanstack/src/components/ui/popover.tsx +50 -0
- package/template/apps/asas-tanstack/src/components/ui/radio-group.tsx +10 -0
- package/template/apps/asas-tanstack/src/components/ui/resizable.tsx +47 -0
- package/template/apps/asas-tanstack/src/components/ui/scroll-area.tsx +52 -0
- package/template/apps/asas-tanstack/src/components/ui/select.tsx +190 -0
- package/template/apps/asas-tanstack/src/components/ui/separator.tsx +23 -0
- package/template/apps/asas-tanstack/src/components/ui/sheet.tsx +127 -0
- package/template/apps/asas-tanstack/src/components/ui/sidebar.tsx +716 -0
- package/template/apps/asas-tanstack/src/components/ui/skeleton.tsx +13 -0
- package/template/apps/asas-tanstack/src/components/ui/slider.tsx +13 -0
- package/template/apps/asas-tanstack/src/components/ui/spinner.tsx +11 -0
- package/template/apps/asas-tanstack/src/components/ui/switch.tsx +8 -0
- package/template/apps/asas-tanstack/src/components/ui/table.tsx +119 -0
- package/template/apps/asas-tanstack/src/components/ui/tabs.tsx +80 -0
- package/template/apps/asas-tanstack/src/components/ui/textarea.tsx +18 -0
- package/template/apps/asas-tanstack/src/components/ui/toggle-group.tsx +8 -0
- package/template/apps/asas-tanstack/src/components/ui/toggle.tsx +44 -0
- package/template/apps/asas-tanstack/src/components/ui/tooltip.tsx +68 -0
- package/template/apps/asas-tanstack/src/copy.ts +870 -0
- package/template/apps/asas-tanstack/src/hooks/use-mobile.ts +19 -0
- package/template/apps/asas-tanstack/src/lib/utils.ts +6 -0
- package/template/apps/asas-tanstack/src/links.ts +38 -0
- package/template/apps/asas-tanstack/src/locale-switch.tsx +26 -0
- package/template/apps/asas-tanstack/src/quiet-abort.ts +25 -0
- package/template/apps/asas-tanstack/src/redirect.ts +20 -0
- package/template/apps/asas-tanstack/src/request-headers.ts +11 -0
- package/template/apps/asas-tanstack/src/routeTree.gen.ts +382 -0
- package/template/apps/asas-tanstack/src/router.tsx +7 -0
- package/template/apps/asas-tanstack/src/routes/(screens)/dashboard/files.ts +4 -0
- package/template/apps/asas-tanstack/src/routes/(screens)/dashboard/screen.json +3883 -0
- package/template/apps/asas-tanstack/src/routes/(screens)/dashboard/types.ts +158 -0
- package/template/apps/asas-tanstack/src/routes/(screens)/dashboard.$.tsx +17 -0
- package/template/apps/asas-tanstack/src/routes/(screens)/dashboard.index.tsx +10 -0
- package/template/apps/asas-tanstack/src/routes/(screens)/dashboard.tsx +13 -0
- package/template/apps/asas-tanstack/src/routes/(screens)/portal/files.ts +4 -0
- package/template/apps/asas-tanstack/src/routes/(screens)/portal/screen.json +1800 -0
- package/template/apps/asas-tanstack/src/routes/(screens)/portal/types.ts +92 -0
- package/template/apps/asas-tanstack/src/routes/(screens)/portal.$.tsx +17 -0
- package/template/apps/asas-tanstack/src/routes/(screens)/portal.index.tsx +10 -0
- package/template/apps/asas-tanstack/src/routes/(screens)/portal.tsx +13 -0
- package/template/apps/asas-tanstack/src/routes/__root.tsx +99 -0
- package/template/apps/asas-tanstack/src/routes/api/$.ts +11 -0
- package/template/apps/asas-tanstack/src/routes/auth.accept-invitation.tsx +101 -0
- package/template/apps/asas-tanstack/src/routes/auth.forgot-password.tsx +94 -0
- package/template/apps/asas-tanstack/src/routes/auth.handoff.ts +39 -0
- package/template/apps/asas-tanstack/src/routes/auth.reset-password.tsx +109 -0
- package/template/apps/asas-tanstack/src/routes/auth.sign-in.tsx +86 -0
- package/template/apps/asas-tanstack/src/routes/auth.sign-up.tsx +122 -0
- package/template/apps/asas-tanstack/src/routes/index.tsx +142 -0
- package/template/apps/asas-tanstack/src/routes/unauthorized.tsx +122 -0
- package/template/apps/asas-tanstack/src/screen-form.tsx +34 -0
- package/template/apps/asas-tanstack/src/screen-list.tsx +139 -0
- package/template/apps/asas-tanstack/src/screen-names.ts +10 -0
- package/template/apps/asas-tanstack/src/screens.tsx +868 -0
- package/template/apps/asas-tanstack/src/server.ts +16 -0
- package/template/apps/asas-tanstack/src/slide.ts +22 -0
- package/template/apps/asas-tanstack/src/start.ts +57 -0
- package/template/apps/asas-tanstack/src/styles.css +159 -0
- package/template/apps/asas-tanstack/src/theme.ts +5 -0
- package/template/apps/asas-tanstack/tsconfig.json +19 -0
- package/template/apps/asas-tanstack/vite.config.ts +28 -0
- package/template/package.json +16 -0
- package/template/templates/asas/.env.example +16 -0
- package/template/templates/asas/components.json +22 -0
- package/template/templates/asas/mithaq.hints.json +25 -0
- package/template/templates/asas/package.json +38 -0
- package/template/templates/asas/src/asas.ts +93 -0
- package/template/templates/asas/src/audit-log/audit-log.ts +187 -0
- package/template/templates/asas/src/audit-log/sink.ts +89 -0
- package/template/templates/asas/src/audit-log/ui/activity.tsx +243 -0
- package/template/templates/asas/src/courses/courses.ts +612 -0
- package/template/templates/asas/src/courses/ui/archive-button.tsx +25 -0
- package/template/templates/asas/src/courses/ui/fee-cell.tsx +19 -0
- package/template/templates/asas/src/courses/ui/no-courses-on-offer.tsx +11 -0
- package/template/templates/asas/src/courses/ui/no-courses.tsx +13 -0
- package/template/templates/asas/src/courses/ui/on-offer.ts +6 -0
- package/template/templates/asas/src/courses/ui/status-cell.tsx +31 -0
- package/template/templates/asas/src/enrollments/enrollments.ts +137 -0
- package/template/templates/asas/src/enrollments/ui/session-cell.tsx +65 -0
- package/template/templates/asas/src/kayan/auth/user/account.access.ts +8 -0
- package/template/templates/asas/src/kayan/auth/user/account.ts +31 -0
- package/template/templates/asas/src/kayan/auth/user/index.ts +18 -0
- package/template/templates/asas/src/kayan/auth/user/invitation.access.ts +4 -0
- package/template/templates/asas/src/kayan/auth/user/invitation.ts +27 -0
- package/template/templates/asas/src/kayan/auth/user/member.access.ts +10 -0
- package/template/templates/asas/src/kayan/auth/user/member.screens.ts +37 -0
- package/template/templates/asas/src/kayan/auth/user/member.ts +25 -0
- package/template/templates/asas/src/kayan/auth/user/organization.access.ts +20 -0
- package/template/templates/asas/src/kayan/auth/user/organization.screens.ts +37 -0
- package/template/templates/asas/src/kayan/auth/user/organization.ts +24 -0
- package/template/templates/asas/src/kayan/auth/user/organizationRole.access.ts +8 -0
- package/template/templates/asas/src/kayan/auth/user/organizationRole.ts +25 -0
- package/template/templates/asas/src/kayan/auth/user/session.access.ts +8 -0
- package/template/templates/asas/src/kayan/auth/user/session.ts +28 -0
- package/template/templates/asas/src/kayan/auth/user/user.access.ts +29 -0
- package/template/templates/asas/src/kayan/auth/user/user.screens.ts +45 -0
- package/template/templates/asas/src/kayan/auth/user/user.ts +31 -0
- package/template/templates/asas/src/kayan/auth/user/verification.access.ts +8 -0
- package/template/templates/asas/src/kayan/auth/user/verification.ts +23 -0
- package/template/templates/asas/src/local-users/local-users.ts +143 -0
- package/template/templates/asas/src/media/media.ts +137 -0
- package/template/templates/asas/src/media/ui/preview.tsx +143 -0
- package/template/templates/asas/src/member-roles/member-roles.ts +207 -0
- package/template/templates/asas/src/messages/account.json +106 -0
- package/template/templates/asas/src/messages/auditLog.json +186 -0
- package/template/templates/asas/src/messages/courses.json +270 -0
- package/template/templates/asas/src/messages/enrollments.json +42 -0
- package/template/templates/asas/src/messages/invitation.json +66 -0
- package/template/templates/asas/src/messages/localUsers.json +42 -0
- package/template/templates/asas/src/messages/media.json +66 -0
- package/template/templates/asas/src/messages/member.json +42 -0
- package/template/templates/asas/src/messages/memberRoles.json +42 -0
- package/template/templates/asas/src/messages/mithaq.json +170 -0
- package/template/templates/asas/src/messages/organization.json +50 -0
- package/template/templates/asas/src/messages/organizationRole.json +50 -0
- package/template/templates/asas/src/messages/roles.json +58 -0
- package/template/templates/asas/src/messages/session.json +82 -0
- package/template/templates/asas/src/messages/sessions.json +106 -0
- package/template/templates/asas/src/messages/settings.json +66 -0
- package/template/templates/asas/src/messages/tags.json +38 -0
- package/template/templates/asas/src/messages/user.json +90 -0
- package/template/templates/asas/src/messages/verification.json +50 -0
- package/template/templates/asas/src/migrations/20260920080701_parched_tombstone/migration.sql +177 -0
- package/template/templates/asas/src/migrations/20260920080701_parched_tombstone/snapshot.json +2169 -0
- package/template/templates/asas/src/migrations/20260920230505_zippy_ben_urich/migration.sql +1 -0
- package/template/templates/asas/src/migrations/20260920230505_zippy_ben_urich/snapshot.json +2182 -0
- package/template/templates/asas/src/migrations/20260920231219_slim_retro_girl/migration.sql +20 -0
- package/template/templates/asas/src/migrations/20260920231219_slim_retro_girl/snapshot.json +2409 -0
- package/template/templates/asas/src/migrations/20260922082945_military_ironclad/migration.sql +15 -0
- package/template/templates/asas/src/migrations/20260922082945_military_ironclad/snapshot.json +2627 -0
- package/template/templates/asas/src/migrations/20260922112630_bitter_chat/migration.sql +5 -0
- package/template/templates/asas/src/migrations/20260922112630_bitter_chat/snapshot.json +2691 -0
- package/template/templates/asas/src/migrations/20260923235915_foamy_rachel_grey/migration.sql +8 -0
- package/template/templates/asas/src/migrations/20260923235915_foamy_rachel_grey/snapshot.json +2795 -0
- package/template/templates/asas/src/migrations/20260926145709_clean_the_initiative/migration.sql +3 -0
- package/template/templates/asas/src/migrations/20260926145709_clean_the_initiative/snapshot.json +2834 -0
- package/template/templates/asas/src/migrations/20260927212525_bent_prowler/migration.sql +9 -0
- package/template/templates/asas/src/migrations/20260927212525_bent_prowler/snapshot.json +2870 -0
- package/template/templates/asas/src/migrations/20260927223441_tranquil_bromley/migration.sql +1 -0
- package/template/templates/asas/src/migrations/20260927223441_tranquil_bromley/snapshot.json +2881 -0
- package/template/templates/asas/src/migrations/20260928030047_outgoing_wraith/migration.sql +15 -0
- package/template/templates/asas/src/migrations/20260928030047_outgoing_wraith/snapshot.json +3073 -0
- package/template/templates/asas/src/migrations/20260929024407_grey_morlun/migration.sql +21 -0
- package/template/templates/asas/src/migrations/20260929024407_grey_morlun/snapshot.json +3098 -0
- package/template/templates/asas/src/migrations/20260929130530_bored_jackal/migration.sql +21 -0
- package/template/templates/asas/src/migrations/20260929130530_bored_jackal/snapshot.json +3124 -0
- package/template/templates/asas/src/migrations/20260930102924_material_newton_destine/migration.sql +32 -0
- package/template/templates/asas/src/migrations/20260930102924_material_newton_destine/snapshot.json +3324 -0
- package/template/templates/asas/src/migrations/20261003022353_clumsy_taskmaster/migration.sql +2 -0
- package/template/templates/asas/src/migrations/20261003022353_clumsy_taskmaster/snapshot.json +3350 -0
- package/template/templates/asas/src/migrations/20261003143249_premium_red_shift/migration.sql +21 -0
- package/template/templates/asas/src/migrations/20261003143249_premium_red_shift/snapshot.json +3635 -0
- package/template/templates/asas/src/migrations/20261008215349_square_norrin_radd/migration.sql +8 -0
- package/template/templates/asas/src/migrations/20261008215349_square_norrin_radd/snapshot.json +3635 -0
- package/template/templates/asas/src/migrations/20261008230204_many_scarecrow/migration.sql +18 -0
- package/template/templates/asas/src/migrations/20261008230204_many_scarecrow/snapshot.json +3635 -0
- package/template/templates/asas/src/migrations/20261010005521_elite_giant_girl/migration.sql +18 -0
- package/template/templates/asas/src/migrations/20261010005521_elite_giant_girl/snapshot.json +3635 -0
- package/template/templates/asas/src/migrations/20261010120822_needy_thunderbolt/migration.sql +11 -0
- package/template/templates/asas/src/migrations/20261010120822_needy_thunderbolt/snapshot.json +3667 -0
- package/template/templates/asas/src/migrations/20261012000752_organization_ownership/migration.sql +48 -0
- package/template/templates/asas/src/migrations/20261012000752_organization_ownership/snapshot.json +3891 -0
- package/template/templates/asas/src/migrations/drizzle.config.ts +11 -0
- package/template/templates/asas/src/migrations/schema.ts +29 -0
- package/template/templates/asas/src/mithaq.ts +406 -0
- package/template/templates/asas/src/pages.ts +74 -0
- package/template/templates/asas/src/platform-http.ts +96 -0
- package/template/templates/asas/src/rich-text-nodes.ts +11 -0
- package/template/templates/asas/src/roles/grants.ts +47 -0
- package/template/templates/asas/src/roles/roles.ts +184 -0
- package/template/templates/asas/src/roles/ui/role-form.tsx +226 -0
- package/template/templates/asas/src/roles/ui/roles.tsx +166 -0
- package/template/templates/asas/src/roles.ts +16 -0
- package/template/templates/asas/src/seed.ts +325 -0
- package/template/templates/asas/src/sessions/sessions.ts +155 -0
- package/template/templates/asas/src/settings/settings.ts +69 -0
- package/template/templates/asas/src/statements.ts +11 -0
- package/template/templates/asas/src/steps/expected-updated-at.ts +41 -0
- package/template/templates/asas/src/storage/defaults.ts +156 -0
- package/template/templates/asas/src/storage/index.ts +95 -0
- package/template/templates/asas/src/storage/local.ts +143 -0
- package/template/templates/asas/src/storage/r2.ts +5 -0
- package/template/templates/asas/src/storage/s3.ts +91 -0
- package/template/templates/asas/src/storage/uploadthing.ts +59 -0
- package/template/templates/asas/src/tags/tags.ts +80 -0
- package/template/templates/asas/src/tenant-access.ts +221 -0
- package/template/templates/asas/src/tenant-roles.ts +262 -0
- package/template/templates/asas/src/ui/app-shell.tsx +260 -0
- package/template/templates/asas/src/ui/kpi-card.tsx +25 -0
- package/template/templates/asas/src/ui/record-page.tsx +50 -0
- package/template/templates/asas/src/ui/rich-text-nodes.tsx +15 -0
- package/template/templates/asas/src/ui/screen-nav.tsx +28 -0
- package/template/templates/asas/src/ui/session-labels.tsx +36 -0
- package/template/templates/asas/src/ui/table-page.tsx +9 -0
- package/template/templates/asas/src/ui/top-shell.tsx +60 -0
- package/template/templates/asas/src/ui-dashboard/dashboard.tsx +294 -0
- package/template/templates/asas/src/ui-dashboard/members.tsx +630 -0
- package/template/templates/asas/src/ui-dashboard/theme-provider.tsx +10 -0
- package/template/templates/asas/src/ui-dashboard/versions.tsx +432 -0
- package/template/templates/asas/src/ui-platform/home.tsx +63 -0
- package/template/templates/asas/src/ui-platform/organization-actions.tsx +114 -0
- package/template/templates/asas/src/ui-platform/record-page.tsx +30 -0
- package/template/templates/asas/src/ui-platform/role-cells.tsx +52 -0
- package/template/templates/asas/src/ui-platform/user-actions.tsx +251 -0
- package/template/templates/asas/src/ui-portal/home.tsx +77 -0
- package/template/templates/asas/src/ui-portal/page.tsx +11 -0
- package/template/templates/auth/package.json +14 -0
- package/template/templates/auth/src/index.ts +690 -0
- package/template/templates/auth/src/platform-roles.ts +87 -0
- package/README.md +0 -3
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { sql } from 'mithaq/drizzle'
|
|
2
|
+
import type { NodePgDatabase } from 'mithaq/drizzle/node-postgres'
|
|
3
|
+
import { assignableRole, conflict, defaultFields, defaultOperations, denied, type Ctx, type WriteTools } from 'mithaq'
|
|
4
|
+
import { defineKayan, platformUi, rows, organization } from '../mithaq.ts'
|
|
5
|
+
import { platformList, platformRecord } from '../pages.ts'
|
|
6
|
+
import { tenantRoles } from '../roles.ts'
|
|
7
|
+
import { platformReads } from '../tenant-access.ts'
|
|
8
|
+
import { managesRoles, OWNER, OWNER_ROLE } from '../roles/grants.ts'
|
|
9
|
+
|
|
10
|
+
const role = { field: 'role', cell: platformUi('role-cells.tsx#RoleName') } as const
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Nobody takes from themselves the role that lets them manage roles: their own
|
|
14
|
+
* `administrator`, or any role holding a key that manages roles. Another member
|
|
15
|
+
* holding the same keys removes it.
|
|
16
|
+
*
|
|
17
|
+
* A custom role's keys are read as the actor, through the role kayan's own
|
|
18
|
+
* access, so a role the actor may not read is refused rather than taken off
|
|
19
|
+
* unchecked. It guards a member's own row; two administrators removing each
|
|
20
|
+
* other at once are `managerRemains`' to refuse.
|
|
21
|
+
*/
|
|
22
|
+
const keepsOwnManager = async (ctx: Ctx, tools: WriteTools): Promise<Ctx> => {
|
|
23
|
+
const before = ctx.dataBefore
|
|
24
|
+
const me = (ctx.actor as { id?: unknown } | undefined)?.id
|
|
25
|
+
if (!before || me === undefined || before.user !== me) return ctx
|
|
26
|
+
const after = { ...before, ...(ctx.data as Record<string, unknown>) }
|
|
27
|
+
if (tools.kind === 'update' && after.user === before.user && after.role === before.role) return ctx
|
|
28
|
+
const role = String(before.role)
|
|
29
|
+
const roles = (tools.kayans as { roles: { find(input: object): Promise<{ docs: { permissions?: unknown }[] }> } }).roles
|
|
30
|
+
const keys = Object.hasOwn(tenantRoles, role)
|
|
31
|
+
? tenantRoles[role as keyof typeof tenantRoles].permissions
|
|
32
|
+
: (await roles.find({ where: { name: { equals: role } } })).docs.flatMap((row) => (Array.isArray(row.permissions) ? (row.permissions as string[]) : []))
|
|
33
|
+
if (!managesRoles(keys)) return ctx
|
|
34
|
+
throw denied({
|
|
35
|
+
message: `Forbidden: role "${role}" is what lets this member manage roles, so it is not taken from themselves. Another member who may manage roles removes it.`,
|
|
36
|
+
key: 'error.forbidden.own_role',
|
|
37
|
+
params: { kayan: ctx.kayan.name, role },
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** The write's transaction, which is drizzle's here. */
|
|
42
|
+
const txOf = (ctx: Ctx) => ctx.tx as NodePgDatabase
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* How many assignments of one tenant name one role, counted inside the write's
|
|
46
|
+
* own transaction rather than read as the actor: a number leaves this function
|
|
47
|
+
* and no row does, so a role's author needs no `memberRoles` key to learn
|
|
48
|
+
* whether a name is still carried.
|
|
49
|
+
*/
|
|
50
|
+
export const assignedCount = async ({ ctx, tenantId, role }: { ctx: Ctx; tenantId: unknown; role: string }): Promise<number> => {
|
|
51
|
+
const [found] = (
|
|
52
|
+
await txOf(ctx).execute<{ total: number }>(sql`select count(*)::int as total from member_roles where organization_id = ${String(tenantId)} and role = ${role}`)
|
|
53
|
+
).rows
|
|
54
|
+
return found?.total ?? 0
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* What a write changes about who manages roles: an assignment removed, or
|
|
59
|
+
* moved to another member or role, or a custom role's keys, which are `[]`
|
|
60
|
+
* when it is deleted.
|
|
61
|
+
*/
|
|
62
|
+
type Change = { assignment: Readonly<Record<string, unknown>>; becomes?: { user: unknown; role: unknown } } | { role: string; keys: readonly string[] }
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* **Every tenant keeps a member who may manage roles**: one holding a role whose
|
|
66
|
+
* keys `managesRoles` answers for, or the organization's owner, who always holds
|
|
67
|
+
* `administrator`. A write that would leave none is refused 409
|
|
68
|
+
* `error.conflict.last_manager`. Removing the owner's own `administrator` row
|
|
69
|
+
* changes nothing the owner holds, so it is refused too, 403
|
|
70
|
+
* `error.forbidden.owner_role`.
|
|
71
|
+
*
|
|
72
|
+
* The check runs under `pg_advisory_xact_lock` on the tenant, held to the end of
|
|
73
|
+
* the write's transaction, and every guarded write takes the same lock first, so
|
|
74
|
+
* two administrators removing each other at once are serialized and the second
|
|
75
|
+
* reads the first's removal. `FOR UPDATE` on the manager assignments would not
|
|
76
|
+
* do: which assignments manage roles also depends on the roles table, and a role
|
|
77
|
+
* losing its keys touches no assignment row.
|
|
78
|
+
*
|
|
79
|
+
* Rows are read through the store rather than as the actor, because the answer
|
|
80
|
+
* is about every member of the tenant and the actor may read few of them;
|
|
81
|
+
* nothing read leaves this function but the refusal.
|
|
82
|
+
*/
|
|
83
|
+
export const managerRemains = async ({ ctx, tenantId, change }: { ctx: Ctx; tenantId: unknown; change: Change }): Promise<void> => {
|
|
84
|
+
const tx = txOf(ctx)
|
|
85
|
+
const tenant = String(tenantId)
|
|
86
|
+
await tx.execute(sql`select pg_advisory_xact_lock(hashtext('mithaq.managers'), hashtext(${tenant}))`)
|
|
87
|
+
const owners = (
|
|
88
|
+
await tx.execute<{ user: string }>(
|
|
89
|
+
sql`select user_id as "user" from member where organization_id = ${tenant} and ${OWNER} = any(string_to_array(role, ','))`,
|
|
90
|
+
)
|
|
91
|
+
).rows.map((row) => row.user)
|
|
92
|
+
if ('assignment' in change) {
|
|
93
|
+
const { assignment, becomes } = change
|
|
94
|
+
if (assignment.role === OWNER_ROLE && owners.includes(String(assignment.user)) && (becomes?.role !== assignment.role || becomes.user !== assignment.user)) {
|
|
95
|
+
throw denied({
|
|
96
|
+
message: `Forbidden: the organization's owner always holds "${OWNER_ROLE}", so the row saying so is not taken from them.`,
|
|
97
|
+
key: 'error.forbidden.owner_role',
|
|
98
|
+
params: { kayan: ctx.kayan.name, role: OWNER_ROLE },
|
|
99
|
+
})
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (owners.length) return
|
|
103
|
+
const assigned = (await tx.execute<{ id: string; user: string; role: string }>(sql`select id, user_id as "user", role from member_roles where organization_id = ${tenant}`)).rows
|
|
104
|
+
const custom = new Map<string, readonly string[]>(
|
|
105
|
+
(await tx.execute<{ name: string; permissions: string[] }>(sql`select name, permissions from roles where organization_id = ${tenant}`)).rows.map((row) => [row.name, row.permissions] as const),
|
|
106
|
+
)
|
|
107
|
+
if ('keys' in change) custom.set(change.role, change.keys)
|
|
108
|
+
const keysOf = (role: string) => (Object.hasOwn(tenantRoles, role) ? tenantRoles[role as keyof typeof tenantRoles].permissions : (custom.get(role) ?? []))
|
|
109
|
+
const after = assigned.flatMap((row) => {
|
|
110
|
+
if (!('assignment' in change) || row.id !== change.assignment.id) return [row]
|
|
111
|
+
return change.becomes ? [{ ...row, role: String(change.becomes.role) }] : []
|
|
112
|
+
})
|
|
113
|
+
if (after.some((row) => managesRoles(keysOf(row.role)))) return
|
|
114
|
+
throw conflict({
|
|
115
|
+
message: `This write would leave the tenant with no member who may manage roles, so it is refused. Give another member such a role first.`,
|
|
116
|
+
key: 'error.conflict.last_manager',
|
|
117
|
+
params: { kayan: ctx.kayan.name },
|
|
118
|
+
})
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** `managerRemains` for an assignment's update or delete; an update that neither moves the row nor changes its role changes nothing. */
|
|
122
|
+
const keepsAManager = async (ctx: Ctx, tools: WriteTools): Promise<Ctx> => {
|
|
123
|
+
const before = ctx.dataBefore
|
|
124
|
+
if (!before) return ctx
|
|
125
|
+
const after = tools.kind === 'update' ? { ...before, ...(ctx.data as Record<string, unknown>) } : undefined
|
|
126
|
+
if (after && after.user === before.user && after.role === before.role) return ctx
|
|
127
|
+
await managerRemains({ ctx, tenantId: before.organization, change: { assignment: before, ...(after && { becomes: { user: after.user, role: after.role } }) } })
|
|
128
|
+
return ctx
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Who holds which of this project's roles, per tenant: one row per member per
|
|
133
|
+
* role. It exists so that Better Auth's own `member.role` never carries a
|
|
134
|
+
* business role name beside its governance one: a role name holding a comma would
|
|
135
|
+
* be accepted by `create-role` and could never be assigned again, because that
|
|
136
|
+
* column is comma-delimited.
|
|
137
|
+
*
|
|
138
|
+
* The access target reads it straight from the store while the actor is being
|
|
139
|
+
* made, filtered on this tenant and this member, so another tenant's row is
|
|
140
|
+
* never in what comes back.
|
|
141
|
+
*/
|
|
142
|
+
export const memberRoles = defineKayan({
|
|
143
|
+
name: 'memberRoles',
|
|
144
|
+
dbName: 'member_roles',
|
|
145
|
+
targets: {
|
|
146
|
+
// Every organization's rows on the platform, read-only, and each row's
|
|
147
|
+
// record. An assignment is looked for by its person, is titled by them, and
|
|
148
|
+
// reads its role by the role's label, never its slug.
|
|
149
|
+
platform: {
|
|
150
|
+
useAsTitle: 'user',
|
|
151
|
+
pages: {
|
|
152
|
+
...platformList('/member-roles', { columns: ['user', role, 'organization'], filters: ['organization', 'user', 'role'], search: ['user.name', 'user.email'] }),
|
|
153
|
+
...platformRecord({ path: '/member-roles/:id', main: [{ section: 'assignment', label: { en: 'Assignment', ar: 'الإسناد' }, fields: ['user', role] }] }),
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
// No dashboard page and so no nav entry: a member's roles are changed on the
|
|
157
|
+
// Members page's sheet, which writes these rows through the operations below,
|
|
158
|
+
// guards and all.
|
|
159
|
+
service: {
|
|
160
|
+
operations: {
|
|
161
|
+
...defaultOperations,
|
|
162
|
+
// The gate in front of the store step: the runner has parsed by then, so
|
|
163
|
+
// the column is a string, and the write has not happened, so a refused
|
|
164
|
+
// assignment leaves no row. Without it a custom role holding
|
|
165
|
+
// `memberRoles.create` assigns itself `administrator`. It is handed the
|
|
166
|
+
// tenant roles alone, so a platform role such as `support` reads as an
|
|
167
|
+
// unknown custom role and is refused 400. `'roles'` is the kayan it reads
|
|
168
|
+
// the tenant's custom roles from.
|
|
169
|
+
create: { steps: ({ steps }) => [assignableRole(tenantRoles, 'roles'), steps.insert] },
|
|
170
|
+
update: { steps: ({ steps }) => [assignableRole(tenantRoles, 'roles'), keepsOwnManager, keepsAManager, steps.update] },
|
|
171
|
+
// Removing an assignment is measured the way handing it out is. Without it
|
|
172
|
+
// an actor delegated `memberRoles.delete` removes the tenant's only
|
|
173
|
+
// administrator row. The guard reads the row the store holds, because a
|
|
174
|
+
// delete names no column.
|
|
175
|
+
delete: { steps: ({ steps }) => [assignableRole(tenantRoles, 'roles'), keepsOwnManager, keepsAManager, steps.remove] },
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
// Its own rows, since the inherited table would close the instructor's
|
|
180
|
+
// delete here. Every platform role reads the assignments of every tenant in
|
|
181
|
+
// the platform app and changes none; in the tenant app `assignedRoles` omits
|
|
182
|
+
// the platform slugs.
|
|
183
|
+
access: rows({
|
|
184
|
+
'*': { create: true, read: true, update: true, delete: true },
|
|
185
|
+
...platformReads,
|
|
186
|
+
}),
|
|
187
|
+
/** A member holds a role once per tenant. A second assignment answers 409 `error.conflict.unique`. */
|
|
188
|
+
indexes: [{ within: 'organization', unique: [['user', 'role']] }],
|
|
189
|
+
fields: {
|
|
190
|
+
...defaultFields,
|
|
191
|
+
organization,
|
|
192
|
+
user: {
|
|
193
|
+
kind: 'relationship',
|
|
194
|
+
label: { ar: 'العضو', en: 'Member' },
|
|
195
|
+
relationTo: 'user',
|
|
196
|
+
// The assignment goes with the member: a deleted user holds no role, and
|
|
197
|
+
// `restrict`, which a required relationship takes by default, would leave a
|
|
198
|
+
// row nothing can reach standing in the way of the delete.
|
|
199
|
+
rules: { required: true, index: true, onDelete: 'cascade' },
|
|
200
|
+
},
|
|
201
|
+
role: {
|
|
202
|
+
kind: 'text',
|
|
203
|
+
label: { ar: 'الدور', en: 'Role' },
|
|
204
|
+
rules: { required: true, maxLength: 60, index: true },
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
})
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
{
|
|
2
|
+
"accessToken.invalid": {
|
|
3
|
+
"ar": "هذا ليس نصا.",
|
|
4
|
+
"en": "This is not text."
|
|
5
|
+
},
|
|
6
|
+
"accessToken.required": {
|
|
7
|
+
"ar": "هذا الحقل مطلوب.",
|
|
8
|
+
"en": "This field is required."
|
|
9
|
+
},
|
|
10
|
+
"accessTokenExpiresAt.invalid": {
|
|
11
|
+
"ar": "هذا ليس تاريخا ووقتا.",
|
|
12
|
+
"en": "This is not a date and time."
|
|
13
|
+
},
|
|
14
|
+
"accessTokenExpiresAt.required": {
|
|
15
|
+
"ar": "هذا الحقل مطلوب.",
|
|
16
|
+
"en": "This field is required."
|
|
17
|
+
},
|
|
18
|
+
"accountId.invalid": {
|
|
19
|
+
"ar": "هذا ليس نصا.",
|
|
20
|
+
"en": "This is not text."
|
|
21
|
+
},
|
|
22
|
+
"accountId.required": {
|
|
23
|
+
"ar": "هذا الحقل مطلوب.",
|
|
24
|
+
"en": "This field is required."
|
|
25
|
+
},
|
|
26
|
+
"createdAt.invalid": {
|
|
27
|
+
"ar": "هذا ليس تاريخا ووقتا.",
|
|
28
|
+
"en": "This is not a date and time."
|
|
29
|
+
},
|
|
30
|
+
"createdAt.required": {
|
|
31
|
+
"ar": "هذا الحقل مطلوب.",
|
|
32
|
+
"en": "This field is required."
|
|
33
|
+
},
|
|
34
|
+
"id.invalid": {
|
|
35
|
+
"ar": "هذا ليس نصا.",
|
|
36
|
+
"en": "This is not text."
|
|
37
|
+
},
|
|
38
|
+
"id.required": {
|
|
39
|
+
"ar": "هذا الحقل مطلوب.",
|
|
40
|
+
"en": "This field is required."
|
|
41
|
+
},
|
|
42
|
+
"idToken.invalid": {
|
|
43
|
+
"ar": "هذا ليس نصا.",
|
|
44
|
+
"en": "This is not text."
|
|
45
|
+
},
|
|
46
|
+
"idToken.required": {
|
|
47
|
+
"ar": "هذا الحقل مطلوب.",
|
|
48
|
+
"en": "This field is required."
|
|
49
|
+
},
|
|
50
|
+
"password.invalid": {
|
|
51
|
+
"ar": "هذا ليس نصا.",
|
|
52
|
+
"en": "This is not text."
|
|
53
|
+
},
|
|
54
|
+
"password.required": {
|
|
55
|
+
"ar": "هذا الحقل مطلوب.",
|
|
56
|
+
"en": "This field is required."
|
|
57
|
+
},
|
|
58
|
+
"providerId.invalid": {
|
|
59
|
+
"ar": "هذا ليس نصا.",
|
|
60
|
+
"en": "This is not text."
|
|
61
|
+
},
|
|
62
|
+
"providerId.required": {
|
|
63
|
+
"ar": "هذا الحقل مطلوب.",
|
|
64
|
+
"en": "This field is required."
|
|
65
|
+
},
|
|
66
|
+
"refreshToken.invalid": {
|
|
67
|
+
"ar": "هذا ليس نصا.",
|
|
68
|
+
"en": "This is not text."
|
|
69
|
+
},
|
|
70
|
+
"refreshToken.required": {
|
|
71
|
+
"ar": "هذا الحقل مطلوب.",
|
|
72
|
+
"en": "This field is required."
|
|
73
|
+
},
|
|
74
|
+
"refreshTokenExpiresAt.invalid": {
|
|
75
|
+
"ar": "هذا ليس تاريخا ووقتا.",
|
|
76
|
+
"en": "This is not a date and time."
|
|
77
|
+
},
|
|
78
|
+
"refreshTokenExpiresAt.required": {
|
|
79
|
+
"ar": "هذا الحقل مطلوب.",
|
|
80
|
+
"en": "This field is required."
|
|
81
|
+
},
|
|
82
|
+
"scope.invalid": {
|
|
83
|
+
"ar": "هذا ليس نصا.",
|
|
84
|
+
"en": "This is not text."
|
|
85
|
+
},
|
|
86
|
+
"scope.required": {
|
|
87
|
+
"ar": "هذا الحقل مطلوب.",
|
|
88
|
+
"en": "This field is required."
|
|
89
|
+
},
|
|
90
|
+
"updatedAt.invalid": {
|
|
91
|
+
"ar": "هذا ليس تاريخا ووقتا.",
|
|
92
|
+
"en": "This is not a date and time."
|
|
93
|
+
},
|
|
94
|
+
"updatedAt.required": {
|
|
95
|
+
"ar": "هذا الحقل مطلوب.",
|
|
96
|
+
"en": "This field is required."
|
|
97
|
+
},
|
|
98
|
+
"userId.invalid": {
|
|
99
|
+
"ar": "اختر عنصرًا من القائمة.",
|
|
100
|
+
"en": "Pick one of the listed entries."
|
|
101
|
+
},
|
|
102
|
+
"userId.required": {
|
|
103
|
+
"ar": "هذا الحقل مطلوب.",
|
|
104
|
+
"en": "This field is required."
|
|
105
|
+
}
|
|
106
|
+
}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
{
|
|
2
|
+
"action.archive": {
|
|
3
|
+
"ar": "أُرشف",
|
|
4
|
+
"en": "Archived"
|
|
5
|
+
},
|
|
6
|
+
"action.archiveMany": {
|
|
7
|
+
"ar": "أُرشف",
|
|
8
|
+
"en": "Archived"
|
|
9
|
+
},
|
|
10
|
+
"action.create": {
|
|
11
|
+
"ar": "أُنشئ",
|
|
12
|
+
"en": "Created"
|
|
13
|
+
},
|
|
14
|
+
"action.delete": {
|
|
15
|
+
"ar": "حُذف",
|
|
16
|
+
"en": "Deleted"
|
|
17
|
+
},
|
|
18
|
+
"action.deleteMany": {
|
|
19
|
+
"ar": "حُذف",
|
|
20
|
+
"en": "Deleted"
|
|
21
|
+
},
|
|
22
|
+
"action.restoreVersion": {
|
|
23
|
+
"ar": "استُعيد إصدار",
|
|
24
|
+
"en": "Restored a version"
|
|
25
|
+
},
|
|
26
|
+
"action.update": {
|
|
27
|
+
"ar": "حُدِّث",
|
|
28
|
+
"en": "Updated"
|
|
29
|
+
},
|
|
30
|
+
"action.updateMany": {
|
|
31
|
+
"ar": "حُدِّث",
|
|
32
|
+
"en": "Updated"
|
|
33
|
+
},
|
|
34
|
+
"activity": {
|
|
35
|
+
"ar": "النشاط",
|
|
36
|
+
"en": "Activity"
|
|
37
|
+
},
|
|
38
|
+
"actor": {
|
|
39
|
+
"ar": "المنفذ",
|
|
40
|
+
"en": "Actor"
|
|
41
|
+
},
|
|
42
|
+
"actor.invalid": {
|
|
43
|
+
"ar": "هذا ليس نصا.",
|
|
44
|
+
"en": "This is not text."
|
|
45
|
+
},
|
|
46
|
+
"actor.required": {
|
|
47
|
+
"ar": "هذا الحقل مطلوب.",
|
|
48
|
+
"en": "This field is required."
|
|
49
|
+
},
|
|
50
|
+
"changes": {
|
|
51
|
+
"ar": "التغييرات",
|
|
52
|
+
"en": "Changes"
|
|
53
|
+
},
|
|
54
|
+
"changes.invalid": {
|
|
55
|
+
"ar": "هذا ليس نصا.",
|
|
56
|
+
"en": "This is not text."
|
|
57
|
+
},
|
|
58
|
+
"changes.required": {
|
|
59
|
+
"ar": "هذا الحقل مطلوب.",
|
|
60
|
+
"en": "This field is required."
|
|
61
|
+
},
|
|
62
|
+
"command": {
|
|
63
|
+
"ar": "الأمر {command} ({user})",
|
|
64
|
+
"en": "the command {command} ({user})"
|
|
65
|
+
},
|
|
66
|
+
"empty": {
|
|
67
|
+
"ar": "لم يتغير شيء هنا بعد.",
|
|
68
|
+
"en": "Nothing has changed here yet."
|
|
69
|
+
},
|
|
70
|
+
"event": {
|
|
71
|
+
"ar": "{action} بواسطة {actor}",
|
|
72
|
+
"en": "{action} by {actor}"
|
|
73
|
+
},
|
|
74
|
+
"eventYou": {
|
|
75
|
+
"ar": "{action} بواسطتك",
|
|
76
|
+
"en": "{action} by You"
|
|
77
|
+
},
|
|
78
|
+
"failed": {
|
|
79
|
+
"ar": "تعذرت قراءة النشاط.",
|
|
80
|
+
"en": "The activity could not be read."
|
|
81
|
+
},
|
|
82
|
+
"id.invalid": {
|
|
83
|
+
"ar": "هذا ليس معرفا فريدا.",
|
|
84
|
+
"en": "This is not a unique identifier."
|
|
85
|
+
},
|
|
86
|
+
"id.required": {
|
|
87
|
+
"ar": "هذا الحقل مطلوب.",
|
|
88
|
+
"en": "This field is required."
|
|
89
|
+
},
|
|
90
|
+
"impersonated": {
|
|
91
|
+
"ar": "{staff} بصفة {member}",
|
|
92
|
+
"en": "{staff} as {member}"
|
|
93
|
+
},
|
|
94
|
+
"impersonatedBy": {
|
|
95
|
+
"ar": "انتحل الصفة",
|
|
96
|
+
"en": "Impersonated by"
|
|
97
|
+
},
|
|
98
|
+
"impersonatedBy.invalid": {
|
|
99
|
+
"ar": "هذا ليس نصا.",
|
|
100
|
+
"en": "This is not text."
|
|
101
|
+
},
|
|
102
|
+
"impersonatedBy.required": {
|
|
103
|
+
"ar": "هذا الحقل مطلوب.",
|
|
104
|
+
"en": "This field is required."
|
|
105
|
+
},
|
|
106
|
+
"kayan": {
|
|
107
|
+
"ar": "الكيان",
|
|
108
|
+
"en": "Kayan"
|
|
109
|
+
},
|
|
110
|
+
"kayan.invalid": {
|
|
111
|
+
"ar": "هذا ليس نصا.",
|
|
112
|
+
"en": "This is not text."
|
|
113
|
+
},
|
|
114
|
+
"kayan.maxLength": {
|
|
115
|
+
"ar": "القيمة طويلة جدًا.",
|
|
116
|
+
"en": "The value is too long."
|
|
117
|
+
},
|
|
118
|
+
"kayan.required": {
|
|
119
|
+
"ar": "هذا الحقل مطلوب.",
|
|
120
|
+
"en": "This field is required."
|
|
121
|
+
},
|
|
122
|
+
"loading": {
|
|
123
|
+
"ar": "جارٍ تحميل النشاط…",
|
|
124
|
+
"en": "Loading activity…"
|
|
125
|
+
},
|
|
126
|
+
"more": {
|
|
127
|
+
"ar": "عرض الأقدم",
|
|
128
|
+
"en": "Show older"
|
|
129
|
+
},
|
|
130
|
+
"none": {
|
|
131
|
+
"ar": "لم يتغير حقل يمكنك قراءته.",
|
|
132
|
+
"en": "No field you may read changed."
|
|
133
|
+
},
|
|
134
|
+
"operation": {
|
|
135
|
+
"ar": "العملية",
|
|
136
|
+
"en": "Operation"
|
|
137
|
+
},
|
|
138
|
+
"operation.invalid": {
|
|
139
|
+
"ar": "هذا ليس نصا.",
|
|
140
|
+
"en": "This is not text."
|
|
141
|
+
},
|
|
142
|
+
"operation.maxLength": {
|
|
143
|
+
"ar": "القيمة طويلة جدًا.",
|
|
144
|
+
"en": "The value is too long."
|
|
145
|
+
},
|
|
146
|
+
"operation.required": {
|
|
147
|
+
"ar": "هذا الحقل مطلوب.",
|
|
148
|
+
"en": "This field is required."
|
|
149
|
+
},
|
|
150
|
+
"organization": {
|
|
151
|
+
"ar": "المؤسسة",
|
|
152
|
+
"en": "Organization"
|
|
153
|
+
},
|
|
154
|
+
"plural": {
|
|
155
|
+
"ar": "سجل التدقيق",
|
|
156
|
+
"en": "Audit log"
|
|
157
|
+
},
|
|
158
|
+
"record": {
|
|
159
|
+
"ar": "السجل",
|
|
160
|
+
"en": "Record"
|
|
161
|
+
},
|
|
162
|
+
"record.invalid": {
|
|
163
|
+
"ar": "هذا ليس نصا.",
|
|
164
|
+
"en": "This is not text."
|
|
165
|
+
},
|
|
166
|
+
"record.required": {
|
|
167
|
+
"ar": "هذا الحقل مطلوب.",
|
|
168
|
+
"en": "This field is required."
|
|
169
|
+
},
|
|
170
|
+
"singular": {
|
|
171
|
+
"ar": "سجل تدقيق",
|
|
172
|
+
"en": "Audit entry"
|
|
173
|
+
},
|
|
174
|
+
"someone": {
|
|
175
|
+
"ar": "شخص ما",
|
|
176
|
+
"en": "Someone"
|
|
177
|
+
},
|
|
178
|
+
"system": {
|
|
179
|
+
"ar": "النظام",
|
|
180
|
+
"en": "The system"
|
|
181
|
+
},
|
|
182
|
+
"you": {
|
|
183
|
+
"ar": "أنت",
|
|
184
|
+
"en": "You"
|
|
185
|
+
}
|
|
186
|
+
}
|