@rebasepro/app 0.25.1 → 0.26.0

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.
Files changed (38) hide show
  1. package/README.md +1 -1
  2. package/dist/RlsSimulatorPanel-DOfmVgM3.js +403 -0
  3. package/dist/RlsSimulatorPanel-DOfmVgM3.js.map +1 -0
  4. package/dist/collections/form-layout.d.ts +30 -27
  5. package/dist/components/LanguageToggle.d.ts +9 -0
  6. package/dist/components/LoginView/index.d.ts +7 -0
  7. package/dist/components/index.d.ts +1 -0
  8. package/dist/components/studio/RlsSimulatorBar.d.ts +39 -0
  9. package/dist/components/studio/RlsSimulatorPanel.d.ts +29 -0
  10. package/dist/contexts/RlsSimulationContext.d.ts +47 -0
  11. package/dist/contexts/index.d.ts +1 -0
  12. package/dist/core/effective_role_state.d.ts +9 -0
  13. package/dist/{de-DyzL3TA9.js → de-3yzzpuZj.js} +108 -1
  14. package/dist/de-3yzzpuZj.js.map +1 -0
  15. package/dist/debug.js +96 -46
  16. package/dist/{es-DJCi9Za4.js → es-mnyTaRkK.js} +108 -1
  17. package/dist/es-mnyTaRkK.js.map +1 -0
  18. package/dist/{fr-Ie-LqMS1.js → fr-nJHADzlI.js} +108 -1
  19. package/dist/fr-nJHADzlI.js.map +1 -0
  20. package/dist/{hi-D7t90uiv.js → hi-B9_iunnL.js} +108 -1
  21. package/dist/hi-B9_iunnL.js.map +1 -0
  22. package/dist/hooks/useBuildEffectiveRoleController.d.ts +9 -3
  23. package/dist/hooks/usePermissions.d.ts +4 -0
  24. package/dist/hooks/useUnsavedChangesDialog.d.ts +7 -1
  25. package/dist/i18n/RebaseI18nProvider.d.ts +11 -0
  26. package/dist/index.es.js +2747 -2555
  27. package/dist/index.es.js.map +1 -1
  28. package/dist/{it-DPvaMOt6.js → it-DoEtz-OK.js} +108 -1
  29. package/dist/it-DoEtz-OK.js.map +1 -0
  30. package/dist/{pt-DfaXMf_W.js → pt-DT26AmBU.js} +108 -1
  31. package/dist/pt-DT26AmBU.js.map +1 -0
  32. package/package.json +7 -7
  33. package/dist/de-DyzL3TA9.js.map +0 -1
  34. package/dist/es-DJCi9Za4.js.map +0 -1
  35. package/dist/fr-Ie-LqMS1.js.map +0 -1
  36. package/dist/hi-D7t90uiv.js.map +0 -1
  37. package/dist/it-DPvaMOt6.js.map +0 -1
  38. package/dist/pt-DfaXMf_W.js.map +0 -1
@@ -0,0 +1,29 @@
1
+ /**
2
+ * The "Simulate access" pill and banner themselves. Loaded on demand by the
3
+ * wrappers in `RlsSimulatorBar.tsx`: only an administrator ever sees them, so
4
+ * nobody else downloads them before the login screen paints.
5
+ */
6
+ import React from "react";
7
+ import { type RlsSimulatorBarProps } from "./RlsSimulatorBar.js";
8
+ /**
9
+ * "Simulate access": the app bar pill that runs every data view as a role, a
10
+ * user or a service key, so an administrator sees exactly the rows and fields
11
+ * that identity's row-level security lets it read.
12
+ *
13
+ * Shown only to an administrator, and only when the data views ride a client
14
+ * that can derive a simulated one. The server checks the first again on every
15
+ * request: anyone else sending the simulation headers gets a 403.
16
+ *
17
+ * @group Components
18
+ */
19
+ export declare function RlsSimulatorBarPanel({ className, compact, side, align, portalContainer }: RlsSimulatorBarProps): React.JSX.Element | null;
20
+ /**
21
+ * The banner every screen shows while access is simulated: who the data views
22
+ * run as, how many collections show that identity nothing, how many fields its
23
+ * roles cannot read — and the way out.
24
+ *
25
+ * @group Components
26
+ */
27
+ export declare function RlsSimulationBannerPanel({ className }: {
28
+ className?: string;
29
+ }): React.JSX.Element | null;
@@ -0,0 +1,47 @@
1
+ import React from "react";
2
+ import type { AccessSimulation } from "@rebasepro/types";
3
+ /**
4
+ * How the banner names what is simulated — a key's name, a user's email —
5
+ * which the headers alone do not carry.
6
+ *
7
+ * @group Models
8
+ */
9
+ export type RlsSimulationLabel = {
10
+ kind: "role";
11
+ role: string;
12
+ userId?: string;
13
+ } | {
14
+ kind: "user";
15
+ user: string;
16
+ } | {
17
+ kind: "apiKey";
18
+ name: string;
19
+ keyPrefix: string;
20
+ };
21
+ /**
22
+ * The RLS simulator's state: what the admin panel's data views run as.
23
+ *
24
+ * While `simulation` is set, every data view reads through a client derived
25
+ * with `client.simulate()`, so a grid shows exactly the rows and fields that
26
+ * role, user or key can read. `null` is the signed-in administrator.
27
+ *
28
+ * @group Models
29
+ */
30
+ export interface RlsSimulationController {
31
+ /**
32
+ * Whether simulation is possible here: the client can derive a simulated
33
+ * one, and the default data source is that client (not a direct driver).
34
+ */
35
+ available: boolean;
36
+ simulation: AccessSimulation | null;
37
+ label: RlsSimulationLabel | null;
38
+ setSimulation(simulation: AccessSimulation | null, label?: RlsSimulationLabel | null): void;
39
+ }
40
+ export declare const RlsSimulationContext: React.Context<RlsSimulationController>;
41
+ /**
42
+ * The RLS simulator's state, for the bar that sets it and the banner that
43
+ * shows it.
44
+ *
45
+ * @group Hooks and utilities
46
+ */
47
+ export declare function useRlsSimulation(): RlsSimulationController;
@@ -16,3 +16,4 @@ export * from "./CustomizationControllerContext.js";
16
16
  export * from "./ComponentOverrideContext.js";
17
17
  export * from "./CollectionScopeContext.js";
18
18
  export * from "./CollectionResolverContext.js";
19
+ export * from "./RlsSimulationContext.js";
@@ -0,0 +1,9 @@
1
+ import type { EffectiveRoleController } from "@rebasepro/types";
2
+ /**
3
+ * The effective role controller `<Rebase>` falls back to when the host passes
4
+ * none. Kept apart from the deprecated public hook
5
+ * (`useBuildEffectiveRoleController`) so building it does not report a
6
+ * deprecation the app never used, and out of the hooks barrel so it is not a
7
+ * public export.
8
+ */
9
+ export declare function useEffectiveRoleState(): EffectiveRoleController;
@@ -196,6 +196,30 @@ var de = {
196
196
  error_firestore_index: "Für diese Abfrage ist ein Firestore-Index erforderlich.",
197
197
  realtime_connection_lost_title: "Live-Aktualisierungen pausiert",
198
198
  realtime_connection_lost_body: "Die Verbindung zum Server ist unterbrochen, daher ist das Angezeigte möglicherweise nicht mehr aktuell. Es wird aktualisiert, sobald die Verbindung wieder besteht.",
199
+ rls_simulate_access: "Zugriff simulieren",
200
+ rls_simulate_access_description: "Jede Sammlung so sehen, wie eine Rolle, ein Benutzer oder ein Dienstschlüssel sie sähe: Zeilen und Felder, die ihre Sicherheit auf Zeilenebene verbirgt, fehlen.",
201
+ rls_simulate_tab_role: "Rolle",
202
+ rls_simulate_tab_user: "Benutzer",
203
+ rls_simulate_tab_api_key: "API-Schlüssel",
204
+ rls_simulate_user_id_optional: "Als Benutzer-ID (optional)",
205
+ rls_simulate_apply: "Simulieren",
206
+ rls_simulate_stop: "Simulation beenden",
207
+ rls_simulate_search_users: "Benutzer suchen",
208
+ rls_simulate_no_users: "Keine Benutzer gefunden.",
209
+ rls_simulate_no_api_keys: "Keine aktiven Dienstschlüssel.",
210
+ rls_simulate_options_error: "Was simuliert werden kann, ließ sich nicht laden: {{message}}",
211
+ rls_simulate_users_error: "Benutzer ließen sich nicht laden: {{message}}",
212
+ rls_simulation_viewing_as_role: "Ansicht als Rolle {{role}}",
213
+ rls_simulation_viewing_as_role_user: "Ansicht als {{user}} mit der Rolle {{role}}",
214
+ rls_simulation_viewing_as_user: "Ansicht als Benutzer {{user}}",
215
+ rls_simulation_viewing_as_api_key: "Ansicht als API-Schlüssel {{name}} ({{prefix}}…)",
216
+ rls_simulation_hidden_collections: "{{count}} Sammlungen verborgen",
217
+ rls_simulation_hidden_collections_one: "1 Sammlung verborgen",
218
+ rls_simulation_masked_columns: "{{count}} Spalten durch RLS maskiert",
219
+ rls_simulation_masked_columns_one: "1 Spalte durch RLS maskiert",
220
+ rls_simulation_counting: "Es wird gezählt, was diese Identität lesen kann…",
221
+ rls_simulation_count_failed: "Was diese Identität lesen kann, ließ sich nicht zählen: {{message}}",
222
+ rls_simulation_note: "Datenansichten zeigen nur die Zeilen und Felder, die diese Identität lesen kann. Bearbeiten ist während der Simulation ausgeschaltet: Beenden Sie die Simulation, um Änderungen vorzunehmen. Live-Aktualisierungen pausieren.",
199
223
  create_index: "Index erstellen",
200
224
  value_is_not_reference: "Wert ist keine Referenz.",
201
225
  click_to_edit: "Klicken zum Bearbeiten",
@@ -1381,6 +1405,61 @@ var de = {
1381
1405
  studio_rls_nothing_changed: "Nichts geändert, daher wurde nichts gespeichert.",
1382
1406
  studio_branches_unavailable_title: "Datenbank-Branching ist nicht verfügbar",
1383
1407
  studio_branches_unavailable_body: "Branching benötigt ein Postgres-Backend mit einer Admin-Verbindung. Setze ADMIN_CONNECTION_STRING in der Umgebung des Backends.",
1408
+ studio_branch_diff_tab_schema: "Schema und RLS-Richtlinien",
1409
+ studio_branch_diff_tab_data: "Datenänderungen",
1410
+ studio_branch_diff_tab_details: "Einzelheiten",
1411
+ studio_branch_diff_merge: "In {{target}} zusammenführen",
1412
+ studio_branch_diff_failed: "Dieser Branch konnte nicht verglichen werden",
1413
+ studio_branch_diff_denied_title: "Du kannst diesen Branch nicht prüfen",
1414
+ studio_branch_diff_denied_hint: "Einen Branch zu prüfen erfordert den Scope database:write: Sein Diff zeigt Zeilen beider Datenbanken, gelesen außerhalb der Row-Level-Security.",
1415
+ studio_branch_diff_unreadable: "Der Server antwortete mit etwas, das kein Branch-Diff ist.",
1416
+ studio_branch_diff_no_api: "Dieses Panel hat keine Backend-Adresse, von der es den Diff des Branches lesen könnte.",
1417
+ studio_branch_diff_fork_unknown: "Der Zeitpunkt, zu dem dieser Branch erstellt wurde, ließ sich nicht lesen. Jede abweichende Zeile zählt daher als Änderung des Branches, und ein Zusammenführen würde auch rückgängig machen, was {{target}} seitdem geändert hat.",
1418
+ studio_branch_diff_schema_empty: "Keine Schema- oder Richtlinienänderungen gegenüber {{target}}.",
1419
+ studio_branch_diff_schema_not_merged: "Schema- und Richtlinienänderungen werden zur Prüfung gezeigt. Ein Zusammenführen wendet sie nie an: Sie gehören zu deinen Collections und deren Migrationen.",
1420
+ studio_branch_diff_object_table: "Tabelle",
1421
+ studio_branch_diff_object_column: "Spalte",
1422
+ studio_branch_diff_object_policy: "Richtlinie",
1423
+ studio_branch_diff_object_rls: "Sicherheit auf Zeilenebene",
1424
+ studio_branch_diff_object_constraint: "Constraint",
1425
+ studio_branch_diff_object_index: "Index",
1426
+ studio_branch_diff_object_trigger: "Trigger",
1427
+ studio_branch_diff_object_enum: "Enum-Typ",
1428
+ studio_branch_diff_object_view: "View",
1429
+ studio_branch_diff_object_function: "Funktion",
1430
+ studio_branch_diff_change_added: "Hinzugefügt",
1431
+ studio_branch_diff_change_dropped: "Entfernt",
1432
+ studio_branch_diff_change_altered: "Geändert",
1433
+ studio_branch_diff_data_empty: "Der Branch hat gegenüber {{target}} keine Zeilen geändert.",
1434
+ studio_branch_diff_row_inserted: "Eingefügt",
1435
+ studio_branch_diff_row_updated: "Aktualisiert",
1436
+ studio_branch_diff_row_deleted: "Gelöscht",
1437
+ studio_branch_diff_row_conflict: "Konflikt",
1438
+ studio_branch_diff_conflicts: "{{count}} Konflikte",
1439
+ studio_branch_diff_target_changes: "{{count}} Zeilen wurden seit dem Erstellen des Branches nur in {{target}} geändert. Ein Zusammenführen behält sie.",
1440
+ studio_branch_diff_target_changes_referencing: "{{count}} Zeilen wurden seit dem Erstellen des Branches nur in {{target}} geändert. {{reached}} davon verweisen auf Zeilen, die der Branch gelöscht hat: Ein Merge behält sie, außer der Branch gewinnt diesen Konflikt.",
1441
+ studio_branch_diff_referenced_by: "Auf Zeilen, die der Branch hier gelöscht hat, verweisen noch Zeilen, die {{target}} seit dem Erstellen des Branches geschrieben hat: {{tables}}. Jede zählt als Konflikt.",
1442
+ studio_branch_diff_row_counts: "Zeilen: {{targetCount}} in {{target}}, {{branchCount}} im Branch.",
1443
+ studio_branch_diff_column_change: "Änderung",
1444
+ studio_branch_diff_column_key: "Primärschlüssel",
1445
+ studio_branch_diff_column_values: "Werte",
1446
+ studio_branch_diff_samples_shown: "{{shown}} von {{total}} geänderten Zeilen werden angezeigt.",
1447
+ studio_branch_diff_merge_title: "{{branch}} in {{target}} zusammenführen",
1448
+ studio_branch_diff_merge_writes: "Damit werden die Zeilen des Branches in {{target}} geschrieben: {{inserted}} eingefügt, {{updated}} aktualisiert und {{deleted}} gelöscht.",
1449
+ studio_branch_diff_merge_target_kept: "Nichts, was {{target}} seit dem Erstellen des Branches geändert hat, wird angefasst.",
1450
+ studio_branch_diff_merge_target_kept_count: "Die {{count}} Zeilen, die {{target}} seit dem Erstellen des Branches geändert hat, bleiben unverändert.",
1451
+ studio_branch_diff_merge_schema_skipped: "Die {{count}} Schema- und Richtlinienänderungen werden nicht zusammengeführt. Wende sie mit deinen Migrationen an (rebase db push).",
1452
+ studio_branch_diff_merge_conflicts: "{{count}} Zeilen wurden auf beiden Seiten geändert. Welche Version gewinnt?",
1453
+ studio_branch_diff_merge_referenced_conflicts: "Einige davon sind Zeilen, die der Branch gelöscht hat und auf die noch {{count}} Zeilen verweisen, die {{target}} seitdem geschrieben hat: {{tables}}. Die Version von {{target}} zu behalten, behält diese Zeilen und die Zeilen, die auf sie verweisen.",
1454
+ studio_branch_diff_merge_referenced_reached: "Gewinnt der Branch, werden Zeilen gelöscht, auf die noch {{count}} Zeilen verweisen, die {{target}} seitdem geschrieben hat, und die Fremdschlüssel erreichen diese Zeilen: {{tables}}. Die übrigen Zeilen, die {{target}} seitdem geändert hat, bleiben unverändert.",
1455
+ studio_branch_diff_conflict_abort: "Keine: nichts zusammenführen",
1456
+ studio_branch_diff_conflict_branch: "Die des Branches ({{branch}})",
1457
+ studio_branch_diff_conflict_target: "Die von {{target}}: so lassen, wie sie ist",
1458
+ studio_branch_diff_merge_blocked: "{{count}} Tabellen mit geänderten Zeilen können nicht zusammengeführt werden:",
1459
+ studio_branch_diff_merge_skip_blocked: "Die übrigen Tabellen zusammenführen und diese so lassen",
1460
+ studio_branch_diff_merge_atomic: "Alles wird in einer Transaktion geschrieben oder gar nichts. Hat sich eine der beiden Datenbanken seit dem Lesen dieses Diffs geändert, wird nichts geschrieben und der Diff neu geladen.",
1461
+ studio_branch_diff_merge_confirm: "Zusammenführen",
1462
+ studio_branch_diff_merged: "{{count}} Zeilen in {{target}} zusammengeführt",
1384
1463
  studio_backups_not_configured_title: "Sicherungen sind nicht konfiguriert",
1385
1464
  studio_backups_not_configured_body: "Setze BACKUP_DESTINATION auf einen lokalen Pfad oder eine s3:// bzw. gs://-URL und erstelle dann eine Sicherung mit `rebase db backup` oder einem geplanten Cron-Job.",
1386
1465
  studio_cron_empty_title: "Keine Cron-Jobs registriert",
@@ -1472,6 +1551,34 @@ var de = {
1472
1551
  studio_storage_folder_exists: "Der Ordner „{{name}}“ existiert bereits",
1473
1552
  studio_storage_folder_created: "Ordner „{{name}}“ erstellt",
1474
1553
  studio_storage_create_folder_failed: "Ordner konnte nicht erstellt werden",
1554
+ studio_branches_empty: "Noch keine Branches. Erstelle einen, um mit einer isolierten Kopie der Datenbank zu arbeiten.",
1555
+ studio_branches_create_action: "Branch erstellen",
1556
+ studio_branches_empty_detail: "Erstelle einen Branch, um loszulegen",
1557
+ studio_branches_select_prompt: "Wähle einen Branch aus, um die Details zu sehen",
1558
+ studio_branches_list_from: "von {{parent}} · {{when}}",
1559
+ studio_branches_created_from: "Erstellt aus",
1560
+ studio_branches_branch_name: "Branch-Name",
1561
+ studio_branches_source_database: "Quelldatenbank",
1562
+ studio_branches_created: "Erstellt",
1563
+ studio_branches_size: "Größe",
1564
+ studio_branches_usage_title: "So verwendest du diesen Branch",
1565
+ studio_branches_usage_switch: "Richte diesen Checkout darauf aus. Jeder spätere Befehl verwendet ihn:",
1566
+ studio_branches_usage_off: "Zurück zur Hauptdatenbank geht es mit:",
1567
+ studio_branches_usage_isolated: "Änderungen in diesem Branch wirken sich nicht auf die Hauptdatenbank aus.",
1568
+ studio_branches_connection_details: "Verbindungsdetails",
1569
+ studio_branches_row_database: "Datenbank:",
1570
+ studio_branches_row_connect: "Verbinden mit:",
1571
+ studio_branches_row_branched_from: "Abgezweigt von:",
1572
+ studio_branches_row_created_at: "Erstellt am:",
1573
+ studio_branches_create_title: "Neuen Branch erstellen",
1574
+ studio_branches_create_body: "Erstelle eine isolierte Kopie der Datenbank. Der Branch ist ein vollständiger Klon der Quelldatenbank zum jetzigen Zeitpunkt.",
1575
+ studio_branches_name_placeholder: "z. B. feature-auth, staging, preview-pr-42",
1576
+ studio_branches_source_main: "Standard (Hauptdatenbank)",
1577
+ studio_branches_creating: "Wird erstellt…",
1578
+ studio_branches_delete_title: "Branch löschen",
1579
+ studio_branches_delete_body: "Möchtest du den Branch „{{name}}“ wirklich endgültig löschen? Diese Aktion kann nicht rückgängig gemacht werden, und alle Daten in diesem Branch gehen verloren.",
1580
+ studio_branches_created_snackbar: "Branch „{{name}}“ erfolgreich erstellt",
1581
+ studio_branches_deleted_snackbar: "Branch „{{name}}“ gelöscht",
1475
1582
  insights_period_last_days: "Letzte {{count}} Tage",
1476
1583
  insights_period_last_days_one: "Letzter Tag",
1477
1584
  insights_previous_period_value: "Vorherige {{count}} Tage: {{value}}",
@@ -1498,4 +1605,4 @@ var de = {
1498
1605
  //#endregion
1499
1606
  export { de };
1500
1607
 
1501
- //# sourceMappingURL=de-DyzL3TA9.js.map
1608
+ //# sourceMappingURL=de-3yzzpuZj.js.map