@rebasepro/admin 0.16.0 → 0.16.1-canary.g2d1aec8

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 (167) hide show
  1. package/dist/{CollectionEditorDialog-D2Vf4C3-.js → CollectionEditorDialog-Cec5jU6R.js} +7 -3
  2. package/dist/{CollectionEditorDialog-D2Vf4C3-.js.map → CollectionEditorDialog-Cec5jU6R.js.map} +1 -1
  3. package/dist/{PropertyEditView-D3NBsK9_.js → PropertyEditView-BuSPZwnQ.js} +2 -2
  4. package/dist/{PropertyEditView-D3NBsK9_.js.map → PropertyEditView-BuSPZwnQ.js.map} +1 -1
  5. package/dist/{RouterCollectionsStudioView-hPB54l3Q.js → RouterCollectionsStudioView-BiNFpEii.js} +4 -4
  6. package/dist/{RouterCollectionsStudioView-hPB54l3Q.js.map → RouterCollectionsStudioView-BiNFpEii.js.map} +1 -1
  7. package/dist/SchemaChangeDialog-WKIbzS6P.js +327 -0
  8. package/dist/SchemaChangeDialog-WKIbzS6P.js.map +1 -0
  9. package/dist/collection_editor/ConfigControllerProvider.d.ts +4 -4
  10. package/dist/collection_editor/_cms_internals.d.ts +23 -23
  11. package/dist/collection_editor/api/index.d.ts +1 -1
  12. package/dist/collection_editor/extensibility_types.d.ts +1 -1
  13. package/dist/collection_editor/index.d.ts +21 -21
  14. package/dist/collection_editor/liveSchemaClient.d.ts +170 -0
  15. package/dist/collection_editor/serializable_utils.d.ts +1 -1
  16. package/dist/collection_editor/types/collection_editor_controller.d.ts +1 -1
  17. package/dist/collection_editor/types/config_controller.d.ts +11 -0
  18. package/dist/collection_editor/ui/collection_editor/AICollectionGeneratorPopover.d.ts +1 -1
  19. package/dist/collection_editor/ui/collection_editor/AIModifiedPathsContext.d.ts +1 -1
  20. package/dist/collection_editor/ui/collection_editor/CollectionEditorDialog.d.ts +4 -4
  21. package/dist/collection_editor/ui/collection_editor/CollectionEditorWelcomeView.d.ts +1 -1
  22. package/dist/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.d.ts +2 -2
  23. package/dist/collection_editor/ui/collection_editor/CollectionStudioView.d.ts +1 -1
  24. package/dist/collection_editor/ui/collection_editor/CollectionsStudioView.d.ts +2 -2
  25. package/dist/collection_editor/ui/collection_editor/GeneralSettingsForm.d.ts +1 -1
  26. package/dist/collection_editor/ui/collection_editor/PropertyEditView.d.ts +2 -2
  27. package/dist/collection_editor/ui/collection_editor/RouterCollectionStudioView.d.ts +1 -1
  28. package/dist/collection_editor/ui/collection_editor/RouterCollectionsStudioView.d.ts +1 -1
  29. package/dist/collection_editor/ui/collection_editor/SchemaChangeDialog.d.ts +66 -0
  30. package/dist/collection_editor/ui/collection_editor/SubcollectionsEditTab.d.ts +2 -2
  31. package/dist/collection_editor/ui/collection_editor/import/CollectionEditorImportDataPreview.d.ts +1 -1
  32. package/dist/collection_editor/ui/collection_editor/import/CollectionEditorImportMapping.d.ts +1 -1
  33. package/dist/collection_editor/ui/collection_editor/import/clean_import_data.d.ts +1 -1
  34. package/dist/collection_editor/ui/collection_editor/properties/conditions/index.d.ts +6 -6
  35. package/dist/collection_editor/useCollectionEditorController.d.ts +1 -1
  36. package/dist/collection_editor/useCollectionsConfigController.d.ts +1 -1
  37. package/dist/collection_editor/useJsonCollectionsConfigController.d.ts +2 -2
  38. package/dist/collection_editor/useLiveSchemaEditing.d.ts +71 -0
  39. package/dist/collection_editor/useLocalCollectionsConfigController.d.ts +1 -1
  40. package/dist/collection_editor_ui.d.ts +12 -12
  41. package/dist/collection_editor_ui.js +4 -4
  42. package/dist/components/CollectionTableBinding/CollectionTableBinding.d.ts +1 -1
  43. package/dist/components/CollectionTableBinding/PropertyTableCell.d.ts +1 -1
  44. package/dist/components/CollectionTableBinding/fields/TableStorageUpload.d.ts +1 -1
  45. package/dist/components/CollectionTableBinding/index.d.ts +5 -5
  46. package/dist/components/CollectionTableBinding/internal/popup_field/PopupFormField.d.ts +1 -1
  47. package/dist/components/CollectionViewBinding/SlotValue.d.ts +2 -2
  48. package/dist/components/CollectionViewBinding/hooks/useKanbanDragAndDrop.d.ts +1 -1
  49. package/dist/components/EditFormActions.d.ts +1 -1
  50. package/dist/components/EditViewBinding.d.ts +3 -3
  51. package/dist/components/EntityInspector.d.ts +1 -1
  52. package/dist/components/EntityPreviewBinding.d.ts +1 -1
  53. package/dist/components/EntityViewBinding.d.ts +1 -1
  54. package/dist/components/HomePage/index.d.ts +4 -4
  55. package/dist/components/PropertyCollectionView.d.ts +1 -1
  56. package/dist/components/ReferenceWidget.d.ts +1 -1
  57. package/dist/components/admin/index.d.ts +1 -1
  58. package/dist/components/app/AppBar.d.ts +1 -1
  59. package/dist/components/app/index.d.ts +4 -4
  60. package/dist/components/common/index.d.ts +1 -1
  61. package/dist/components/field_configs.d.ts +1 -1
  62. package/dist/components/history/EntityHistoryEntry.d.ts +2 -2
  63. package/dist/components/history/index.d.ts +5 -5
  64. package/dist/components/index.d.ts +45 -45
  65. package/dist/data_export/export/index.d.ts +4 -4
  66. package/dist/data_export/index.d.ts +1 -1
  67. package/dist/data_import/components/DataNewPropertiesMapping.d.ts +1 -1
  68. package/dist/data_import/components/ImportSaveInProgress.d.ts +1 -1
  69. package/dist/data_import/components/index.d.ts +4 -4
  70. package/dist/data_import/hooks/index.d.ts +1 -1
  71. package/dist/data_import/hooks/useImportConfig.d.ts +1 -1
  72. package/dist/data_import/import/ImportCollectionAction.d.ts +1 -1
  73. package/dist/data_import/import/index.d.ts +1 -1
  74. package/dist/data_import/index.d.ts +5 -5
  75. package/dist/data_import/types/index.d.ts +1 -1
  76. package/dist/data_import/utils/file_to_json.d.ts +1 -1
  77. package/dist/data_import/utils/index.d.ts +5 -5
  78. package/dist/editor/components/SlashCommandMenu.d.ts +2 -2
  79. package/dist/editor/components/index.d.ts +5 -5
  80. package/dist/editor/editor.d.ts +2 -2
  81. package/dist/editor/index.d.ts +2 -2
  82. package/dist/editor/nodeViews/ImageComponent.d.ts +1 -1
  83. package/dist/editor/nodeViews/TaskItemComponent.d.ts +1 -1
  84. package/dist/editor/types.d.ts +1 -1
  85. package/dist/{export-oauWlxuu.js → export-BItpoIu0.js} +2 -2
  86. package/dist/{export-oauWlxuu.js.map → export-BItpoIu0.js.map} +1 -1
  87. package/dist/form/EntityForm.d.ts +1 -1
  88. package/dist/form/EntityFormActions.d.ts +1 -1
  89. package/dist/form/EntityFormBinding.d.ts +1 -1
  90. package/dist/form/PropertyFieldBinding.d.ts +1 -1
  91. package/dist/form/components/StorageItemPreview.d.ts +1 -1
  92. package/dist/form/components/index.d.ts +6 -6
  93. package/dist/form/field_bindings/ArrayCustomShapedFieldBinding.d.ts +1 -1
  94. package/dist/form/field_bindings/ArrayOfReferencesFieldBinding.d.ts +1 -1
  95. package/dist/form/field_bindings/BinaryFieldBinding.d.ts +1 -1
  96. package/dist/form/field_bindings/BlockFieldBinding.d.ts +1 -1
  97. package/dist/form/field_bindings/DateTimeFieldBinding.d.ts +1 -1
  98. package/dist/form/field_bindings/GeopointFieldBinding.d.ts +1 -1
  99. package/dist/form/field_bindings/KeyValueFieldBinding.d.ts +1 -1
  100. package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
  101. package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +2 -2
  102. package/dist/form/field_bindings/MultiSelectFieldBinding.d.ts +1 -1
  103. package/dist/form/field_bindings/MultipleRelationFieldBinding.d.ts +1 -1
  104. package/dist/form/field_bindings/ReadOnlyFieldBinding.d.ts +1 -1
  105. package/dist/form/field_bindings/ReferenceFieldBinding.d.ts +1 -1
  106. package/dist/form/field_bindings/RelationFieldBinding.d.ts +1 -1
  107. package/dist/form/field_bindings/RepeatFieldBinding.d.ts +1 -1
  108. package/dist/form/field_bindings/SelectFieldBinding.d.ts +1 -1
  109. package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +1 -1
  110. package/dist/form/field_bindings/SwitchFieldBinding.d.ts +1 -1
  111. package/dist/form/field_bindings/TextFieldBinding.d.ts +1 -1
  112. package/dist/form/field_bindings/UserSelectFieldBinding.d.ts +1 -1
  113. package/dist/form/field_bindings/VectorFieldBinding.d.ts +1 -1
  114. package/dist/form/index.d.ts +24 -24
  115. package/dist/{history-C2cqc0bw.js → history-C7WF14VR.js} +2 -2
  116. package/dist/{history-C2cqc0bw.js.map → history-C7WF14VR.js.map} +1 -1
  117. package/dist/hooks/index.d.ts +16 -16
  118. package/dist/hooks/navigation/contexts/index.d.ts +3 -3
  119. package/dist/hooks/useBuildSideDialogsController.d.ts +1 -1
  120. package/dist/hooks/useSelectionDialog.d.ts +1 -1
  121. package/dist/{import-Bxv5JPm-.js → import-CZgNAlcd.js} +2 -2
  122. package/dist/{import-Bxv5JPm-.js.map → import-CZgNAlcd.js.map} +1 -1
  123. package/dist/index.d.ts +17 -15
  124. package/dist/index.js +238 -21
  125. package/dist/index.js.map +1 -1
  126. package/dist/preview/PropertyPreview.d.ts +1 -1
  127. package/dist/preview/components/ArrayEnumPreview.d.ts +1 -1
  128. package/dist/preview/components/BooleanPreview.d.ts +1 -1
  129. package/dist/preview/components/ImagePreview.d.ts +1 -1
  130. package/dist/preview/components/ReferencePreview.d.ts +1 -1
  131. package/dist/preview/components/RelationPreview.d.ts +1 -1
  132. package/dist/preview/components/StorageThumbnail.d.ts +1 -1
  133. package/dist/preview/components/UrlComponentPreview.d.ts +2 -2
  134. package/dist/preview/components/UserPreview.d.ts +1 -1
  135. package/dist/preview/index.d.ts +24 -24
  136. package/dist/preview/property_previews/ArrayOfMapsPreview.d.ts +1 -1
  137. package/dist/preview/property_previews/ArrayOfReferencesPreview.d.ts +1 -1
  138. package/dist/preview/property_previews/ArrayOfRelationsPreview.d.ts +1 -1
  139. package/dist/preview/property_previews/ArrayOfStorageComponentsPreview.d.ts +1 -1
  140. package/dist/preview/property_previews/ArrayOfStringsPreview.d.ts +1 -1
  141. package/dist/preview/property_previews/ArrayOneOfPreview.d.ts +1 -1
  142. package/dist/preview/property_previews/ArrayPropertyEnumPreview.d.ts +1 -1
  143. package/dist/preview/property_previews/ArrayPropertyPreview.d.ts +1 -1
  144. package/dist/preview/property_previews/MapPropertyPreview.d.ts +1 -1
  145. package/dist/preview/property_previews/NumberPropertyPreview.d.ts +1 -1
  146. package/dist/preview/property_previews/SkeletonPropertyComponent.d.ts +1 -1
  147. package/dist/preview/property_previews/StringPropertyPreview.d.ts +1 -1
  148. package/dist/preview/util.d.ts +1 -1
  149. package/dist/routes/index.d.ts +2 -2
  150. package/dist/types/components/EntityFormActionsProps.d.ts +2 -2
  151. package/dist/types/components/EntityFormProps.d.ts +3 -3
  152. package/dist/types/components/index.d.ts +3 -3
  153. package/dist/types/fields.d.ts +1 -1
  154. package/dist/types/index.d.ts +2 -2
  155. package/dist/util/index.d.ts +5 -5
  156. package/dist/{util-C4qsI1QV.js → util-wrBH4QSB.js} +130 -7
  157. package/dist/util-wrBH4QSB.js.map +1 -0
  158. package/package.json +10 -10
  159. package/src/collection_editor/ConfigControllerProvider.tsx +5 -0
  160. package/src/collection_editor/liveSchemaClient.ts +272 -0
  161. package/src/collection_editor/types/config_controller.tsx +11 -0
  162. package/src/collection_editor/ui/collection_editor/CollectionEditorDialog.tsx +10 -0
  163. package/src/collection_editor/ui/collection_editor/SchemaChangeDialog.tsx +368 -0
  164. package/src/collection_editor/useLiveSchemaEditing.tsx +285 -0
  165. package/src/collection_editor/useLocalCollectionsConfigController.tsx +109 -10
  166. package/src/index.ts +6 -0
  167. package/dist/util-C4qsI1QV.js.map +0 -1
@@ -0,0 +1,170 @@
1
+ /**
2
+ * The panel's client for live schema editing.
3
+ *
4
+ * Three calls, mirroring the routes: ask whether this backend can do it, ask
5
+ * what a change would do, then do it. `plan` and `apply` are deliberately
6
+ * separate here as well as on the server, because a UI that could only
7
+ * try-and-see would be asking somebody to discover that their change is refused
8
+ * by pressing a button on a live database.
9
+ *
10
+ * ## Partial payloads are the caller's problem, not this module's
11
+ *
12
+ * Every call takes the **whole** collection. Live editing computes the proposed
13
+ * state by replacing one collection in the set, so a patch would read as a set
14
+ * of removals — every property it does not mention — and be refused.
15
+ *
16
+ * The editor's own save path posts partials (`saveProperty` follows up with a
17
+ * one-key `collection/save` carrying `partial: true`), so
18
+ * `useLocalCollectionsConfigController` assembles the whole collection before
19
+ * it gets here. Accepting a patch and merging it in this module would put that
20
+ * reconstruction one layer away from the collections it needs to read.
21
+ */
22
+ /** A constraint the change asks for that the statements will not carry. */
23
+ export interface WithheldConstraint {
24
+ target: string;
25
+ kind: "not-null";
26
+ reason: string;
27
+ remedy: string;
28
+ }
29
+ /** What the server says a change would do. Mirrors `SchemaChangePlan`. */
30
+ export interface LiveSchemaPlan {
31
+ applicable: boolean;
32
+ verdict: "safe" | "diverges" | "needs-migration";
33
+ changes: Array<{
34
+ kind: string;
35
+ verdict: "safe" | "diverges" | "needs-migration";
36
+ collection: string;
37
+ property?: string;
38
+ detail: string;
39
+ remedy?: string;
40
+ }>;
41
+ statements: string[];
42
+ files: string[];
43
+ message: string;
44
+ /**
45
+ * Applicable, and still not fully enforced.
46
+ *
47
+ * Not a refusal, so it does not belong in `changes` — but it is the one
48
+ * thing on a plan somebody might want to stop and read, so the dialog gives
49
+ * it its own place rather than another bullet in the list.
50
+ */
51
+ withheldConstraints: WithheldConstraint[];
52
+ }
53
+ export interface LiveSchemaResult {
54
+ applied: boolean;
55
+ applyError?: string;
56
+ committed: {
57
+ sha: string;
58
+ branch: string;
59
+ files: string[];
60
+ };
61
+ statements: string[];
62
+ summary: string;
63
+ withheldConstraints: WithheldConstraint[];
64
+ }
65
+ /**
66
+ * Whether this backend can edit its schema, and what is missing when it cannot.
67
+ *
68
+ * `canPlan` is separate from `enabled` deliberately: previewing a change needs
69
+ * no repository, so a deployment running from a bundle can still show somebody
70
+ * exactly what their change would do. Greying out the preview as well would be
71
+ * a worse answer than the truth.
72
+ */
73
+ export interface LiveSchemaStatus {
74
+ enabled: boolean;
75
+ canPlan: boolean;
76
+ /**
77
+ * Whether *this caller* may apply, as opposed to whether the server can.
78
+ *
79
+ * Applying commits to the repository under an author, and a credential is
80
+ * not an author — so an API key or the service key may preview a change and
81
+ * not make one. Reported here so the panel can grey out the button and say
82
+ * why, rather than letting somebody read a plan, decide, press, and only
83
+ * then be refused.
84
+ */
85
+ canApply: boolean;
86
+ applyRefusedBecause?: string;
87
+ applyRefusedCode?: string;
88
+ repository?: string;
89
+ code?: string;
90
+ reason?: string;
91
+ }
92
+ /**
93
+ * Why live editing is not available here.
94
+ *
95
+ * Distinguished from an ordinary failure because both are expected states with
96
+ * their own explanation, and a UI should say which rather than showing a
97
+ * stack: a Mongo backend will never support this, and a bundle deployment has
98
+ * no source to edit.
99
+ */
100
+ export type LiveSchemaUnavailable = {
101
+ reason: "unsupported";
102
+ message: string;
103
+ } | {
104
+ reason: "no-repository";
105
+ message: string;
106
+ };
107
+ export declare class LiveSchemaError extends Error {
108
+ readonly code: string | undefined;
109
+ readonly changes?: LiveSchemaPlan["changes"] | undefined;
110
+ constructor(message: string, code: string | undefined, changes?: LiveSchemaPlan["changes"] | undefined);
111
+ }
112
+ export interface LiveSchemaClientOptions {
113
+ /** Base for the routes, e.g. `https://api.example.com/api/schema`. */
114
+ baseUrl: string;
115
+ getAuthToken?: () => Promise<string | null> | string | null;
116
+ fetchImpl?: typeof fetch;
117
+ }
118
+ export interface ProposedCollectionChange {
119
+ collectionId: string;
120
+ /**
121
+ * The **whole** collection as it should end up — not a patch. See the
122
+ * module comment: a partial reads as a set of removals.
123
+ */
124
+ collection: Record<string, unknown>;
125
+ }
126
+ export declare function createLiveSchemaClient(options: LiveSchemaClientOptions): {
127
+ /**
128
+ * Whether this backend can edit its schema.
129
+ *
130
+ * Never throws. Every way of failing to get an answer — a backend too
131
+ * old to have the endpoint, an unreachable one, a session that is not
132
+ * an admin — means the same thing to a caller deciding whether to offer
133
+ * the control, and turning that into an exception each caller has to
134
+ * catch would only produce four copies of this `catch`.
135
+ */
136
+ status: () => Promise<LiveSchemaStatus>;
137
+ /** What the change would do. No side effects. */
138
+ plan: (change: ProposedCollectionChange) => Promise<LiveSchemaPlan>;
139
+ /** Commit the change, then apply it. */
140
+ apply: (change: ProposedCollectionChange) => Promise<LiveSchemaResult>;
141
+ };
142
+ /** The client's shape, for the hook and the tests that fake it. */
143
+ export type LiveSchemaClient = ReturnType<typeof createLiveSchemaClient>;
144
+ /**
145
+ * Whether an error means live editing is unavailable here, rather than that the
146
+ * change was wrong.
147
+ *
148
+ * Returns the reason so a caller can say which, and `undefined` for anything
149
+ * else — a refused change is not an unavailable feature, and conflating them
150
+ * would hide the refusal that the user needs to read.
151
+ */
152
+ export declare function asUnavailable(err: unknown): LiveSchemaUnavailable | undefined;
153
+ /** The person closed the dialog without applying. Not an error; an answer. */
154
+ export declare class SchemaChangeCancelled extends Error {
155
+ constructor();
156
+ }
157
+ /**
158
+ * Was this rejection the person saying no?
159
+ *
160
+ * A save has to *reject* when it is cancelled — resolving would leave the form
161
+ * believing it saved. But a caller that treats every rejection as a failure
162
+ * then reports the user's own choice back to them as an error, which is what
163
+ * the collection editor did: a console error and a red snackbar reading "Error
164
+ * persisting collection: The schema change was not applied."
165
+ *
166
+ * Matched by name rather than `instanceof`, which is unreliable the moment two
167
+ * copies of this module end up in one bundle — the class is then a different
168
+ * identity and every check silently answers false.
169
+ */
170
+ export declare function isSchemaChangeCancelled(err: unknown): boolean;
@@ -9,7 +9,7 @@
9
9
  */
10
10
  import { type Properties, type Property } from "@rebasepro/types";
11
11
  import type { AdminCollection } from "@rebasepro/admin-types";
12
- import type { SerializableCollectionConfig, SerializableProperties, SerializableProperty } from "./serializable_types";
12
+ import type { SerializableCollectionConfig, SerializableProperties, SerializableProperty } from "./serializable_types.js";
13
13
  /**
14
14
  * Resolves a collection slug to the collection it names.
15
15
  *
@@ -1,4 +1,4 @@
1
- import { CollectionsConfigController } from "./config_controller";
1
+ import { CollectionsConfigController } from "./config_controller.js";
2
2
  import { Entity, Property } from "@rebasepro/types";
3
3
  import type { AdminCollection } from "@rebasepro/admin-types";
4
4
  /**
@@ -1,3 +1,4 @@
1
+ import type React from "react";
1
2
  import { Property } from "@rebasepro/types";
2
3
  import { NavigationGroupMapping, AdminCollection } from "@rebasepro/admin-types";
3
4
  export interface CollectionsSetupInfo {
@@ -45,6 +46,16 @@ export interface CollectionsConfigController {
45
46
  updateKanbanColumnsOrder: (params: UpdateKanbanColumnsOrderParams) => Promise<void>;
46
47
  navigationEntries: NavigationGroupMapping[];
47
48
  saveNavigationEntries: (entries: NavigationGroupMapping[]) => Promise<void>;
49
+ /**
50
+ * UI this controller needs on screen in order to do its job.
51
+ *
52
+ * A controller whose writes require a confirmation has to be able to ask,
53
+ * and a hook cannot render. `ConfigControllerProvider` renders this beside
54
+ * its children, so the confirmation belongs to whoever supplied the
55
+ * controller rather than to every consumer of it. Optional: most
56
+ * controllers write without asking anybody.
57
+ */
58
+ dialog?: React.ReactNode;
48
59
  }
49
60
  export type UpdateCollectionParams<M extends Record<string, unknown> = Record<string, unknown>> = {
50
61
  id: string;
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { CollectionGenerationCallback, CollectionOperation } from "../../api/generateCollectionApi";
2
+ import { CollectionGenerationCallback, CollectionOperation } from "../../api/generateCollectionApi.js";
3
3
  import type { AdminCollection } from "@rebasepro/admin-types";
4
4
  export interface AICollectionGeneratorPopoverProps {
5
5
  /**
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { CollectionOperation } from "../../api/generateCollectionApi";
2
+ import { CollectionOperation } from "../../api/generateCollectionApi.js";
3
3
  export interface AIModifiedPathsContextType {
4
4
  /** Set of paths that were modified by AI */
5
5
  modifiedPaths: Set<string>;
@@ -1,10 +1,10 @@
1
1
  import * as React from "react";
2
2
  import { Entity, TableMetadata, User } from "@rebasepro/types";
3
3
  import { AdminCollection } from "@rebasepro/admin-types";
4
- import { CollectionsConfigController } from "../../types/config_controller";
5
- import { CollectionInference } from "../../types/collection_inference";
6
- import { CollectionGenerationCallback } from "../../api/generateCollectionApi";
7
- import type { CollectionEditorExtensionProps } from "../../extensibility_types";
4
+ import { CollectionsConfigController } from "../../types/config_controller.js";
5
+ import { CollectionInference } from "../../types/collection_inference.js";
6
+ import { CollectionGenerationCallback } from "../../api/generateCollectionApi.js";
7
+ import type { CollectionEditorExtensionProps } from "../../extensibility_types.js";
8
8
  export interface CollectionEditorDialogProps extends CollectionEditorExtensionProps {
9
9
  open: boolean;
10
10
  isNewCollection: boolean;
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { CollectionGenerationCallback } from "../../api/generateCollectionApi";
2
+ import { CollectionGenerationCallback } from "../../api/generateCollectionApi.js";
3
3
  import type { AdminCollection } from "@rebasepro/admin-types";
4
4
  export declare function CollectionEditorWelcomeView({ path, parentCollection, onContinue, existingCollectionPaths, generateCollection, onAnalyticsEvent, unmappedTables, onImportFromTable }: {
5
5
  path: string;
@@ -1,8 +1,8 @@
1
1
  import React from "react";
2
2
  import { User } from "@rebasepro/types";
3
3
  import { PropertyConfig, AdminCollection } from "@rebasepro/admin-types";
4
- import type { PropertyTypePreset, PropertyType } from "../../extensibility_types";
5
- import type { SerializableProperty, SerializableCollectionConfig } from "../../serializable_types";
4
+ import type { PropertyTypePreset, PropertyType } from "../../extensibility_types.js";
5
+ import type { SerializableProperty, SerializableCollectionConfig } from "../../serializable_types.js";
6
6
  type CollectionEditorFormProps = {
7
7
  showErrors: boolean;
8
8
  isNewCollection: boolean;
@@ -1,5 +1,5 @@
1
1
  import * as React from "react";
2
- import { CollectionEditorDialogProps } from "./CollectionEditorDialog";
2
+ import { CollectionEditorDialogProps } from "./CollectionEditorDialog.js";
3
3
  import type { AdminCollection } from "@rebasepro/admin-types";
4
4
  export type CollectionStudioViewProps = Omit<CollectionEditorDialogProps, "open" | "isNewCollection" | "editedCollectionId" | "handleClose" | "handleCancel"> & {
5
5
  collectionId?: string | "new";
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
- import { CollectionsConfigController } from "../../types/config_controller";
3
- import type { CollectionEditorExtensionProps } from "../../extensibility_types";
2
+ import { CollectionsConfigController } from "../../types/config_controller.js";
3
+ import type { CollectionEditorExtensionProps } from "../../extensibility_types.js";
4
4
  import type { AdminCollection } from "@rebasepro/admin-types";
5
5
  export interface CollectionsStudioViewProps extends CollectionEditorExtensionProps {
6
6
  configController: CollectionsConfigController;
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import type { ExtraCollectionFieldsParams } from "../../extensibility_types";
2
+ import type { ExtraCollectionFieldsParams } from "../../extensibility_types.js";
3
3
  import type { AdminCollection } from "@rebasepro/admin-types";
4
4
  export declare function GeneralSettingsForm({ isNewCollection, existingPaths, existingIds, parentCollection, renderExtraCollectionFields, standalone, }: {
5
5
  isNewCollection: boolean;
@@ -2,8 +2,8 @@ import React from "react";
2
2
  import { FormexController } from "@rebasepro/forms";
3
3
  import { Property } from "@rebasepro/types";
4
4
  import { PropertyConfig, AdminCollection } from "@rebasepro/admin-types";
5
- import type { PropertyTypePreset, PropertyType } from "../../extensibility_types";
6
- import type { SerializableProperty, SerializableCollectionConfig } from "../../serializable_types";
5
+ import type { PropertyTypePreset, PropertyType } from "../../extensibility_types.js";
6
+ import type { SerializableProperty, SerializableCollectionConfig } from "../../serializable_types.js";
7
7
  export type PropertyWithId = Property & {
8
8
  id?: string;
9
9
  conditions?: import("@rebasepro/types").PropertyConditions;
@@ -10,6 +10,6 @@
10
10
  * (which has no react-router dependency).
11
11
  */
12
12
  import React from "react";
13
- import { CollectionStudioViewProps } from "./CollectionStudioView";
13
+ import { CollectionStudioViewProps } from "./CollectionStudioView.js";
14
14
  export type RouterCollectionStudioViewProps = Omit<CollectionStudioViewProps, "onSave" | "onCancel">;
15
15
  export declare function RouterCollectionStudioView(props: RouterCollectionStudioViewProps): React.JSX.Element;
@@ -9,6 +9,6 @@
9
9
  * (which has no react-router dependency).
10
10
  */
11
11
  import React from "react";
12
- import { CollectionsStudioViewProps } from "./CollectionsStudioView";
12
+ import { CollectionsStudioViewProps } from "./CollectionsStudioView.js";
13
13
  export type RouterCollectionsStudioViewProps = Omit<CollectionsStudioViewProps, "activeCollectionId" | "onActiveCollectionChange">;
14
14
  export declare function RouterCollectionsStudioView(props: RouterCollectionsStudioViewProps): React.JSX.Element;
@@ -0,0 +1,66 @@
1
+ /**
2
+ * What a schema change would do, before it does it.
3
+ *
4
+ * The dialog exists because a schema change has three possible verdicts and two
5
+ * of them are refusals. Without a preview, the only way to discover that a
6
+ * change is refused is to press a button on a live database and read what comes
7
+ * back — which is a fine way to learn and a poor way to work.
8
+ *
9
+ * ## What it shows, in the order somebody reads it
10
+ *
11
+ * The verdict first, in a sentence, because it decides whether the rest is
12
+ * worth reading. Then the changes, each with what it does and — when it is
13
+ * refused — what to do instead. Then the things that are easy to skip past and
14
+ * expensive to have skipped: constraints the change asks for that the database
15
+ * will not end up enforcing. The SQL and the file list come last, collapsed,
16
+ * for the reader who wants them; they are the evidence, not the summary.
17
+ *
18
+ * ## Why the button says "Commit and apply"
19
+ *
20
+ * Because that is the order, and the order is the feature. The commit lands
21
+ * first, so a failed apply leaves the repository ahead of the database — the
22
+ * ordinary state of every project between an edit and a deploy, which the next
23
+ * boot reconciles. A button labelled "Save" would be describing a different,
24
+ * worse thing.
25
+ */
26
+ import React from "react";
27
+ import type { LiveSchemaPlan, LiveSchemaResult } from "../../liveSchemaClient.js";
28
+ export interface SchemaChangeDialogProps {
29
+ open: boolean;
30
+ /** The collection being changed, for the title. */
31
+ collectionId: string;
32
+ /** `undefined` while the plan is still being fetched. */
33
+ plan?: LiveSchemaPlan;
34
+ /** Set when planning itself failed — a network error, a refusal, a 500. */
35
+ planError?: string;
36
+ /** Set once the change has been applied, which turns this into a receipt. */
37
+ result?: LiveSchemaResult;
38
+ applying: boolean;
39
+ /** Set when the apply threw rather than returning a result. */
40
+ applyError?: string;
41
+ onConfirm: () => void;
42
+ /**
43
+ * Write the collection source and leave the database alone.
44
+ *
45
+ * Offered only when the change is refused, and it is what keeps the editor
46
+ * usable while it is. Removing a property is the ordinary case: the ensure
47
+ * path has no `DROP COLUMN`, so a removal can never be applied — and
48
+ * refusing the whole save over it would mean a dev could no longer delete a
49
+ * field from a collection they are still designing.
50
+ *
51
+ * This is exactly what the editor did before live editing existed, so it is
52
+ * not a new hazard; the difference is that it now says what it leaves
53
+ * behind instead of reporting success.
54
+ */
55
+ onSourceOnly?: () => void;
56
+ onClose: () => void;
57
+ /**
58
+ * Why this caller may preview but not apply, when that is the case.
59
+ *
60
+ * A person signed in with an API key, most often. Shown next to a disabled
61
+ * button so the refusal arrives while they are deciding rather than after
62
+ * they have decided.
63
+ */
64
+ applyRefusedBecause?: string;
65
+ }
66
+ export declare function SchemaChangeDialog({ open, collectionId, plan, planError, result, applying, applyError, onConfirm, onSourceOnly, onClose, applyRefusedBecause }: SchemaChangeDialogProps): React.JSX.Element;
@@ -1,8 +1,8 @@
1
1
  import React from "react";
2
2
  import { User } from "@rebasepro/types";
3
3
  import { AdminCollection } from "@rebasepro/admin-types";
4
- import { CollectionsConfigController } from "../../types/config_controller";
5
- import { CollectionInference } from "../../types/collection_inference";
4
+ import { CollectionsConfigController } from "../../types/config_controller.js";
5
+ import { CollectionInference } from "../../types/collection_inference.js";
6
6
  export declare function SubcollectionsEditTab({ collection, parentCollection, configController, collectionInference, getUser, parentCollectionSlugs }: {
7
7
  collection: AdminCollection;
8
8
  parentCollection?: AdminCollection;
@@ -1,4 +1,4 @@
1
- import { ImportConfig } from "../../../_cms_internals";
1
+ import { ImportConfig } from "../../../_cms_internals.js";
2
2
  import { Properties } from "@rebasepro/types";
3
3
  export declare function CollectionEditorImportDataPreview({ importConfig, properties, propertiesOrder }: {
4
4
  importConfig: ImportConfig;
@@ -1,4 +1,4 @@
1
- import { ImportConfig } from "../../../../data_import/types";
1
+ import { ImportConfig } from "../../../../data_import/types/index.js";
2
2
  import { PropertyConfig } from "@rebasepro/admin-types";
3
3
  import React from "react";
4
4
  export declare function CollectionEditorImportMapping({ importConfig, propertyConfigs }: {
@@ -1,5 +1,5 @@
1
1
  import { Properties } from "@rebasepro/types";
2
- import { ImportConfig } from "../../../_cms_internals";
2
+ import { ImportConfig } from "../../../_cms_internals.js";
3
3
  export declare function cleanPropertiesFromImport(properties: Properties, parentSlug?: string): {
4
4
  headersMapping: ImportConfig["headersMapping"];
5
5
  properties: Properties;
@@ -1,6 +1,6 @@
1
- export { ConditionsPanel } from "./ConditionsPanel";
2
- export { ConditionsEditor } from "./ConditionsEditor";
3
- export type { ConditionsEditorProps } from "./ConditionsEditor";
4
- export { EnumConditionsEditor } from "./EnumConditionsEditor";
5
- export type { EnumConditionsEditorProps } from "./EnumConditionsEditor";
6
- export { getPropertyPaths, getGroupedPropertyPaths } from "./property_paths";
1
+ export { ConditionsPanel } from "./ConditionsPanel.js";
2
+ export { ConditionsEditor } from "./ConditionsEditor.js";
3
+ export type { ConditionsEditorProps } from "./ConditionsEditor.js";
4
+ export { EnumConditionsEditor } from "./EnumConditionsEditor.js";
5
+ export type { EnumConditionsEditorProps } from "./EnumConditionsEditor.js";
6
+ export { getPropertyPaths, getGroupedPropertyPaths } from "./property_paths.js";
@@ -1,4 +1,4 @@
1
- import { CollectionEditorController } from "./types/collection_editor_controller";
1
+ import { CollectionEditorController } from "./types/collection_editor_controller.js";
2
2
  /**
3
3
  * Hook to access the collection editor controller.
4
4
  * The methods in this controller can be used to open the collection editor dialog.
@@ -1,4 +1,4 @@
1
- import { CollectionsConfigController } from "./types/config_controller";
1
+ import { CollectionsConfigController } from "./types/config_controller.js";
2
2
  /**
3
3
  * Use this hook to access the configuration controller.
4
4
  * You can use it to get the list of collections, and to save/delete collections.
@@ -1,5 +1,5 @@
1
- import type { CollectionsConfigController } from "./types/config_controller";
2
- import type { JsonCollectionStore } from "./serializable_types";
1
+ import type { CollectionsConfigController } from "./types/config_controller.js";
2
+ import type { JsonCollectionStore } from "./serializable_types.js";
3
3
  export interface UseJsonCollectionsConfigControllerOptions {
4
4
  /**
5
5
  * The store adapter for persisting/loading collections.
@@ -0,0 +1,71 @@
1
+ /**
2
+ * The plan-then-confirm flow, as a hook.
3
+ *
4
+ * Owns three things that belong together and nothing else: whether the backend
5
+ * can edit its schema, the plan for the change somebody is making, and the
6
+ * dialog they confirm it in. The config controller calls `reviewChange` and
7
+ * awaits it; everything about *how* the confirmation happens stays here.
8
+ *
9
+ * ## Why `reviewChange` returns a promise that can reject
10
+ *
11
+ * Because the editor needs to know. A save that was cancelled must not leave
12
+ * the form thinking it succeeded — the collection on screen would then differ
13
+ * from the one on disk, and the next save would be computed from the wrong
14
+ * `before`. Rejecting with {@link SchemaChangeCancelled} is how "the person
15
+ * said no" reaches the caller as an outcome rather than as silence.
16
+ */
17
+ import React from "react";
18
+ import { type LiveSchemaClient, type LiveSchemaStatus, type ProposedCollectionChange } from "./liveSchemaClient.js";
19
+ export { SchemaChangeCancelled, isSchemaChangeCancelled } from "./liveSchemaClient.js";
20
+ export interface UseLiveSchemaEditingOptions {
21
+ /** Base for the routes, e.g. `https://api.example.com/api/admin/schema`. */
22
+ baseUrl: string;
23
+ getAuthToken?: () => Promise<string | null> | string | null;
24
+ /**
25
+ * Identity of the signed-in user.
26
+ *
27
+ * Only used to re-ask: whether this backend will accept a schema change
28
+ * depends on who is asking, and the answer to an anonymous probe does not
29
+ * survive a sign-in.
30
+ */
31
+ authKey?: string | null;
32
+ /**
33
+ * Write the collection source and leave the database alone — what the
34
+ * editor did before this existed. Offered in the dialog when a change is
35
+ * refused, so a dev can still delete a field from a collection they are
36
+ * designing. Omit it and the fallback is not offered.
37
+ */
38
+ writeSourceOnly?: (change: ProposedCollectionChange) => Promise<void>;
39
+ /** Swappable for the tests, which have no server. */
40
+ client?: LiveSchemaClient;
41
+ }
42
+ export interface LiveSchemaEditing {
43
+ /** `undefined` until the backend has answered. For rendering. */
44
+ status?: LiveSchemaStatus;
45
+ /**
46
+ * The same answer, for deciding.
47
+ *
48
+ * `status` is undefined for one round trip after mount, and a caller that
49
+ * read it to choose a code path would take the "not available" branch for
50
+ * that window — so a save issued quickly after a page load would silently
51
+ * skip the confirmation and write source only, while the same save a second
52
+ * later would not. Timing-dependent behaviour with no visible difference is
53
+ * the worst shape this could have.
54
+ *
55
+ * Resolves once, cached; never rejects, because every way of failing to get
56
+ * an answer means the same thing to whoever is deciding.
57
+ */
58
+ ready: () => Promise<LiveSchemaStatus>;
59
+ /**
60
+ * Plan the change, show it, and settle when the person has decided.
61
+ *
62
+ * Resolves once the change has been applied — or written source-only, if
63
+ * they chose that. Rejects with {@link SchemaChangeCancelled} if they
64
+ * closed the dialog, and with the underlying error if planning or applying
65
+ * failed in a way they did not choose.
66
+ */
67
+ reviewChange: (change: ProposedCollectionChange) => Promise<void>;
68
+ /** Render this once, high enough that a dialog over the editor is not clipped. */
69
+ dialog: React.ReactNode;
70
+ }
71
+ export declare function useLiveSchemaEditing(options: UseLiveSchemaEditingOptions): LiveSchemaEditing;
@@ -1,4 +1,4 @@
1
- import { CollectionsConfigController } from "./types/config_controller";
1
+ import { CollectionsConfigController } from "./types/config_controller.js";
2
2
  import type { AdminCollection } from "@rebasepro/admin-types";
3
3
  export declare function useLocalCollectionsConfigController(clientOrUrl: any, baseCollections?: AdminCollection[], options?: {
4
4
  readOnly?: boolean;
@@ -1,12 +1,12 @@
1
- export { CollectionEditorDialog } from "./collection_editor/ui/collection_editor/CollectionEditorDialog";
2
- export type { CollectionEditorDialogProps } from "./collection_editor/ui/collection_editor/CollectionEditorDialog";
3
- export { PropertyFormDialog, PropertyForm } from "./collection_editor/ui/collection_editor/PropertyEditView";
4
- export type { PropertyFormProps, OnPropertyChangedParams } from "./collection_editor/ui/collection_editor/PropertyEditView";
5
- export { CollectionStudioView } from "./collection_editor/ui/collection_editor/CollectionStudioView";
6
- export type { CollectionStudioViewProps } from "./collection_editor/ui/collection_editor/CollectionStudioView";
7
- export { CollectionsStudioView } from "./collection_editor/ui/collection_editor/CollectionsStudioView";
8
- export type { CollectionsStudioViewProps } from "./collection_editor/ui/collection_editor/CollectionsStudioView";
9
- export { RouterCollectionStudioView } from "./collection_editor/ui/collection_editor/RouterCollectionStudioView";
10
- export type { RouterCollectionStudioViewProps } from "./collection_editor/ui/collection_editor/RouterCollectionStudioView";
11
- export { RouterCollectionsStudioView } from "./collection_editor/ui/collection_editor/RouterCollectionsStudioView";
12
- export type { RouterCollectionsStudioViewProps } from "./collection_editor/ui/collection_editor/RouterCollectionsStudioView";
1
+ export { CollectionEditorDialog } from "./collection_editor/ui/collection_editor/CollectionEditorDialog.js";
2
+ export type { CollectionEditorDialogProps } from "./collection_editor/ui/collection_editor/CollectionEditorDialog.js";
3
+ export { PropertyFormDialog, PropertyForm } from "./collection_editor/ui/collection_editor/PropertyEditView.js";
4
+ export type { PropertyFormProps, OnPropertyChangedParams } from "./collection_editor/ui/collection_editor/PropertyEditView.js";
5
+ export { CollectionStudioView } from "./collection_editor/ui/collection_editor/CollectionStudioView.js";
6
+ export type { CollectionStudioViewProps } from "./collection_editor/ui/collection_editor/CollectionStudioView.js";
7
+ export { CollectionsStudioView } from "./collection_editor/ui/collection_editor/CollectionsStudioView.js";
8
+ export type { CollectionsStudioViewProps } from "./collection_editor/ui/collection_editor/CollectionsStudioView.js";
9
+ export { RouterCollectionStudioView } from "./collection_editor/ui/collection_editor/RouterCollectionStudioView.js";
10
+ export type { RouterCollectionStudioViewProps } from "./collection_editor/ui/collection_editor/RouterCollectionStudioView.js";
11
+ export { RouterCollectionsStudioView } from "./collection_editor/ui/collection_editor/RouterCollectionsStudioView.js";
12
+ export type { RouterCollectionsStudioViewProps } from "./collection_editor/ui/collection_editor/RouterCollectionsStudioView.js";
@@ -1,7 +1,7 @@
1
- import { un as useUrlController } from "./util-C4qsI1QV.js";
2
- import { n as CollectionEditorDialog } from "./CollectionEditorDialog-D2Vf4C3-.js";
3
- import { n as PropertyForm, r as PropertyFormDialog } from "./PropertyEditView-D3NBsK9_.js";
4
- import { i as CollectionStudioView, r as CollectionsStudioView, t as RouterCollectionsStudioView } from "./RouterCollectionsStudioView-hPB54l3Q.js";
1
+ import { hn as useUrlController } from "./util-wrBH4QSB.js";
2
+ import { n as CollectionEditorDialog } from "./CollectionEditorDialog-Cec5jU6R.js";
3
+ import { n as PropertyForm, r as PropertyFormDialog } from "./PropertyEditView-BuSPZwnQ.js";
4
+ import { i as CollectionStudioView, r as CollectionsStudioView, t as RouterCollectionsStudioView } from "./RouterCollectionsStudioView-BiNFpEii.js";
5
5
  import "react";
6
6
  import { useSnackbarController } from "@rebasepro/app";
7
7
  import { jsx } from "react/jsx-runtime";
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import { User } from "@rebasepro/types";
3
- import { CollectionTableBindingProps } from "./CollectionTableBindingProps";
3
+ import { CollectionTableBindingProps } from "./CollectionTableBindingProps.js";
4
4
  /**
5
5
  * This component is in charge of rendering a collection table with a high
6
6
  * degree of customization.
@@ -1,7 +1,7 @@
1
1
  import type { Property } from "@rebasepro/types";
2
2
  import React from "react";
3
3
  import { Entity } from "@rebasepro/types";
4
- import { CustomFieldValidator } from "../../form/validation";
4
+ import { CustomFieldValidator } from "../../form/validation.js";
5
5
  export interface PropertyTableCellProps<T> {
6
6
  propertyKey: string;
7
7
  columnIndex: number;
@@ -1,7 +1,7 @@
1
1
  import type { ArrayProperty, StringProperty } from "@rebasepro/types";
2
2
  import * as React from "react";
3
3
  import { Entity } from "@rebasepro/types";
4
- import { PreviewSize } from "../../../types";
4
+ import { PreviewSize } from "../../../types/index.js";
5
5
  /**
6
6
  * Field that allows to upload files to Google Cloud Storage.
7
7
  *
@@ -1,6 +1,6 @@
1
- export { CollectionTableBinding } from "./CollectionTableBinding";
2
- export type { CollectionTableBindingProps } from "./CollectionTableBindingProps";
3
- export * from "./PropertyTableCell";
4
- export * from "./CollectionRowActions";
5
- export * from "./column_utils";
1
+ export { CollectionTableBinding } from "./CollectionTableBinding.js";
2
+ export type { CollectionTableBindingProps } from "./CollectionTableBindingProps.js";
3
+ export * from "./PropertyTableCell.js";
4
+ export * from "./CollectionRowActions.js";
5
+ export * from "./column_utils.js";
6
6
  export { VirtualTableInput } from "@rebasepro/ui";
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import { Entity } from "@rebasepro/types";
3
- import { CustomFieldValidator } from "../../../../form/validation";
3
+ import { CustomFieldValidator } from "../../../../form/validation.js";
4
4
  import type { OnCellValueChangeParams } from "@rebasepro/app";
5
5
  import type { AdminCollection } from "@rebasepro/admin-types";
6
6
  interface PopupFormFieldProps<M extends Record<string, unknown>> {