@rebasepro/admin 0.11.1-canary.gfd39654 → 0.12.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 (124) hide show
  1. package/README.md +1 -1
  2. package/dist/{CollectionEditorDialog-o7F_zbGY.js → CollectionEditorDialog-Dpc75wIZ.js} +56 -260
  3. package/dist/CollectionEditorDialog-Dpc75wIZ.js.map +1 -0
  4. package/dist/{PropertyEditView-DgB2b22q.js → PropertyEditView-DH3XZC2x.js} +2 -2
  5. package/dist/{PropertyEditView-DgB2b22q.js.map → PropertyEditView-DH3XZC2x.js.map} +1 -1
  6. package/dist/{RouterCollectionsStudioView-DaLRgPkj.js → RouterCollectionsStudioView-BZLq4MGp.js} +4 -4
  7. package/dist/{RouterCollectionsStudioView-DaLRgPkj.js.map → RouterCollectionsStudioView-BZLq4MGp.js.map} +1 -1
  8. package/dist/collection_editor/CollectionEditorDialogsContext.d.ts +1 -1
  9. package/dist/collection_editor/_cms_internals.d.ts +1 -1
  10. package/dist/collection_editor/extensibility_types.d.ts +1 -1
  11. package/dist/collection_editor/serializable_types.d.ts +40 -12
  12. package/dist/collection_editor/serializable_utils.d.ts +1 -1
  13. package/dist/collection_editor/ui/collection_editor/CollectionRLSTab.d.ts +1 -11
  14. package/dist/collection_editor_ui.js +4 -4
  15. package/dist/components/CollectionEditorDialogs.d.ts +2 -2
  16. package/dist/components/CollectionTableBinding/column_utils.d.ts +7 -1
  17. package/dist/components/CollectionViewBinding/CollectionListViewBinding.d.ts +2 -2
  18. package/dist/components/DefaultDrawer.d.ts +3 -3
  19. package/dist/components/DrawerNavigationGroup.d.ts +8 -1
  20. package/dist/components/DrawerNavigationItem.d.ts +7 -1
  21. package/dist/components/EditViewBinding.d.ts +1 -1
  22. package/dist/components/RebaseAdmin.d.ts +1 -1
  23. package/dist/components/RebaseAuthGate.d.ts +1 -1
  24. package/dist/components/RebaseLayout.d.ts +5 -1
  25. package/dist/components/RebaseNavigation.d.ts +2 -2
  26. package/dist/components/RebaseRouteDefs.d.ts +1 -1
  27. package/dist/components/RebaseShell.d.ts +6 -1
  28. package/dist/components/RelationSelector.d.ts +14 -0
  29. package/dist/components/SelectableTable/filters/RelationFilterField.d.ts +27 -0
  30. package/dist/components/SelectableTable/filters/null_filter.d.ts +46 -0
  31. package/dist/components/SidePanelProvider.d.ts +2 -2
  32. package/dist/components/app/Scaffold.d.ts +11 -0
  33. package/dist/components/field_configs.d.ts +1 -1
  34. package/dist/{export-BvqhjdEb.js → export-BzIpUdSK.js} +3 -3
  35. package/dist/export-BzIpUdSK.js.map +1 -0
  36. package/dist/form/EntityForm.d.ts +2 -2
  37. package/dist/form/EntityFormBinding.d.ts +5 -5
  38. package/dist/{history-Dz20hH38.js → history-g9688IaK.js} +2 -2
  39. package/dist/{history-Dz20hH38.js.map → history-g9688IaK.js.map} +1 -1
  40. package/dist/hooks/index.d.ts +1 -1
  41. package/dist/hooks/useAdminContext.d.ts +29 -0
  42. package/dist/hooks/useHistory.d.ts +7 -11
  43. package/dist/{import-DINSB-Vu.js → import-BjUG-cIY.js} +2 -2
  44. package/dist/{import-DINSB-Vu.js.map → import-BjUG-cIY.js.map} +1 -1
  45. package/dist/index.js +61 -38
  46. package/dist/index.js.map +1 -1
  47. package/dist/types/components/EntityFormProps.d.ts +1 -1
  48. package/dist/types/fields.d.ts +1 -1
  49. package/dist/{util-BhhfHY1M.js → util-B5fJm1FA.js} +296 -169
  50. package/dist/util-B5fJm1FA.js.map +1 -0
  51. package/package.json +9 -9
  52. package/src/collection_editor/CollectionEditorDialogsContext.tsx +1 -1
  53. package/src/collection_editor/ConfigControllerProvider.tsx +1 -1
  54. package/src/collection_editor/_cms_internals.ts +1 -1
  55. package/src/collection_editor/extensibility_types.ts +1 -1
  56. package/src/collection_editor/index.ts +2 -2
  57. package/src/collection_editor/serializable_types.ts +44 -13
  58. package/src/collection_editor/serializable_utils.ts +68 -59
  59. package/src/collection_editor/ui/collection_editor/CollectionEditorDialog.tsx +1 -1
  60. package/src/collection_editor/ui/collection_editor/CollectionRLSTab.tsx +66 -41
  61. package/src/collection_editor/ui/collection_editor/EntityActionsEditTab.tsx +1 -1
  62. package/src/collection_editor/ui/collection_editor/GetCodeDialog.tsx +1 -1
  63. package/src/collection_editor/ui/collection_editor/SubcollectionsEditTab.tsx +2 -2
  64. package/src/components/CollectionEditorDialogs.tsx +2 -2
  65. package/src/components/CollectionTableBinding/CollectionRowActions.tsx +5 -4
  66. package/src/components/CollectionTableBinding/CollectionTableBinding.tsx +8 -2
  67. package/src/components/CollectionTableBinding/column_utils.tsx +19 -5
  68. package/src/components/CollectionTableBinding/table_bindings.tsx +10 -10
  69. package/src/components/CollectionViewBinding/CollectionListViewBinding.tsx +8 -7
  70. package/src/components/CollectionViewBinding/CollectionViewActions.tsx +2 -2
  71. package/src/components/CollectionViewBinding/CollectionViewBinding.tsx +2 -2
  72. package/src/components/CollectionViewBinding/CollectionViewStartActions.tsx +2 -2
  73. package/src/components/DefaultDrawer.tsx +19 -8
  74. package/src/components/DeleteEntityDialog.tsx +2 -2
  75. package/src/components/DetailViewBinding.tsx +21 -1
  76. package/src/components/DrawerNavigationGroup.tsx +47 -4
  77. package/src/components/DrawerNavigationItem.tsx +19 -5
  78. package/src/components/EditFormActions.tsx +4 -3
  79. package/src/components/EditViewBinding.tsx +1 -1
  80. package/src/components/HomePage/ContentHomePage.tsx +4 -4
  81. package/src/components/RebaseAdmin.tsx +3 -3
  82. package/src/components/RebaseAuthGate.tsx +1 -1
  83. package/src/components/RebaseLayout.tsx +8 -2
  84. package/src/components/RebaseNavigation.tsx +9 -9
  85. package/src/components/RebaseRouteDefs.tsx +2 -2
  86. package/src/components/RebaseShell.tsx +10 -1
  87. package/src/components/RelationSelector.tsx +18 -3
  88. package/src/components/SelectableTable/filters/FilterFieldBinding.tsx +1 -1
  89. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +36 -9
  90. package/src/components/SelectableTable/filters/RelationFilterField.tsx +93 -17
  91. package/src/components/SelectableTable/filters/null_filter.ts +63 -0
  92. package/src/components/SidePanelProvider.tsx +2 -2
  93. package/src/components/app/Scaffold.tsx +16 -1
  94. package/src/data_export/export/ExportCollectionAction.tsx +2 -2
  95. package/src/form/EntityForm.tsx +2 -2
  96. package/src/form/EntityFormActions.tsx +2 -1
  97. package/src/form/EntityFormBinding.tsx +7 -7
  98. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +3 -3
  99. package/src/form/field_bindings/MultipleRelationFieldBinding.tsx +16 -5
  100. package/src/form/field_bindings/ReferenceFieldBinding.tsx +3 -3
  101. package/src/form/field_bindings/RelationFieldBinding.tsx +17 -6
  102. package/src/form/field_bindings/RepeatFieldBinding.tsx +2 -2
  103. package/src/hooks/index.ts +1 -1
  104. package/src/hooks/navigation/useNavigationResolution.ts +10 -4
  105. package/src/hooks/{useCMSContext.tsx → useAdminContext.tsx} +10 -10
  106. package/src/hooks/useHistory.ts +7 -11
  107. package/src/hooks/useResolvedNavigationFrom.tsx +2 -2
  108. package/src/index.ts +4 -4
  109. package/src/preview/PropertyPreview.tsx +6 -6
  110. package/src/preview/components/RelationPreview.tsx +1 -1
  111. package/src/preview/property_previews/ArrayOfMapsPreview.tsx +1 -1
  112. package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +2 -2
  113. package/src/preview/property_previews/ArrayOfRelationsPreview.tsx +2 -2
  114. package/src/preview/property_previews/SkeletonPropertyComponent.tsx +2 -2
  115. package/src/types/components/EntityFormProps.tsx +2 -2
  116. package/src/types/fields.tsx +1 -1
  117. package/dist/CollectionEditorDialog-o7F_zbGY.js.map +0 -1
  118. package/dist/collection_editor/pgColumnToProperty.d.ts +0 -7
  119. package/dist/editor/extensions/Image/index.d.ts +0 -6
  120. package/dist/export-BvqhjdEb.js.map +0 -1
  121. package/dist/hooks/useCMSContext.d.ts +0 -29
  122. package/dist/util-BhhfHY1M.js.map +0 -1
  123. package/src/collection_editor/pgColumnToProperty.ts +0 -291
  124. package/src/editor/extensions/Image/index.ts +0 -133
package/README.md CHANGED
@@ -71,7 +71,7 @@ pnpm add @rebasepro/admin
71
71
  | `useSelectionController` | Row selection state for tables |
72
72
  | `useHistory` | Snapshot change history and version revert |
73
73
  | `useBreadcrumbsController` | Breadcrumb navigation state |
74
- | `useCMSContext` | Access the CMS-level context |
74
+ | `useAdminContext` | Access the admin-level context |
75
75
  | `useResolvedNavigationFrom` | Resolve navigation tree from collection configs |
76
76
 
77
77
  ### Data Import/Export
@@ -1,10 +1,10 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
- import { $t as CollectionTableBinding, A as getFieldId, Ct as convertDataToEntity, Dt as useImportConfig, Et as getInferenceType, Ft as FieldCaption, In as useCollectionRegistryController, Nt as PropertyConfigBadge, Ot as ImportSaveInProgress, Pt as SearchIconsView, St as DataNewPropertiesMapping, Zt as useSelectionController, _ as useCollectionsConfigController, i as namespaceToPropertiesOrderPath, in as useUrlController, k as getFieldConfig, kt as ImportFileUpload, l as validateCollectionJson, m as toSerializableCollectionConfig, n as getFullIdPath, o as CollectionGenerationApiError, on as useNavigationStateController, r as idToPropertiesPath, t as getFullId, vt as useCollectionEditorController, xt as ImportNewPropertyFieldPreview } from "./util-BhhfHY1M.js";
3
- import { a as updatePropertyFromWidget, c as useAIModifiedPaths, i as supportedFields, l as useSafeSnackbarController, n as PropertyForm, o as PropertyTree, r as PropertyFormDialog, s as AIModifiedPathsProvider } from "./PropertyEditView-DgB2b22q.js";
2
+ import { $t as CollectionTableBinding, A as getFieldId, Ct as convertDataToEntity, Dt as useImportConfig, Et as getInferenceType, Ft as FieldCaption, In as useCollectionRegistryController, Nt as PropertyConfigBadge, Ot as ImportSaveInProgress, Pt as SearchIconsView, St as DataNewPropertiesMapping, Zt as useSelectionController, _ as useCollectionsConfigController, i as namespaceToPropertiesOrderPath, in as useUrlController, k as getFieldConfig, kt as ImportFileUpload, l as validateCollectionJson, m as toSerializableCollectionConfig, n as getFullIdPath, o as CollectionGenerationApiError, on as useNavigationStateController, r as idToPropertiesPath, t as getFullId, vt as useCollectionEditorController, xt as ImportNewPropertyFieldPreview } from "./util-B5fJm1FA.js";
3
+ import { a as updatePropertyFromWidget, c as useAIModifiedPaths, i as supportedFields, l as useSafeSnackbarController, n as PropertyForm, o as PropertyTree, r as PropertyFormDialog, s as AIModifiedPathsProvider } from "./PropertyEditView-DH3XZC2x.js";
4
4
  import * as React$1 from "react";
5
5
  import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
6
6
  import { Alert, AppWindow, ArrowLeftIcon, BooleanSwitchWithLabel, Button, Card, CheckIcon, Chip, CircularProgress, CircularProgressCenter, CodeIcon, ColumnsIcon, Container, CopyIcon, DebouncedTextField, Dialog, DialogActions, DialogContent, DialogTitle, ErrorBoundary, FileIcon, FileSearchIcon, FileTextIcon, IconButton, KanbanIcon, KeyIcon, LayoutGridIcon, ListIcon, LoadingButton, Menu, MultiSelect, MultiSelectItem, PanelLeftIcon, Paper, PlusIcon, Select, SelectItem, ShoppingCartIcon, SquareIcon, Tab, TableIcon, Tabs, TextField, ToggleButtonGroup, Tooltip, Trash2Icon, Typography, UserIcon, XIcon, cls, coolIconKeys, defaultBorderMixin, iconSize } from "@rebasepro/ui";
7
- import { getEffectiveSecurityRules, getSubcollections, getTableName, isPropertyBuilder } from "@rebasepro/common";
7
+ import { buildCollectionFromTableMetadata, getEffectiveSecurityRules, getSubcollections, getTableName, isPropertyBuilder } from "@rebasepro/common";
8
8
  import { AIIcon, ConfirmationDialog, ErrorView, IconForView, UnsavedChangesDialog, removeInitialAndTrailingSlashes, useAuthController, useCustomizationController, useLargeLayout, useRebaseContext, useUnsavedChangesDialog } from "@rebasepro/app";
9
9
  import { Field, Formex, clone, getIn, useCreateFormex, useFormex } from "@rebasepro/forms";
10
10
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -696,7 +696,7 @@ function GetCodeDialog({ collection, onOpenChange, open }) {
696
696
  variant: "body2",
697
697
  className: "my-4 mb-8",
698
698
  children: [
699
- "If you want to customise the collection in code, you can add this collection code to your CMS app configuration. More info in the ",
699
+ "If you want to customise the collection in code, you can add this collection code to your admin app configuration. More info in the ",
700
700
  /* @__PURE__ */ jsx("a", {
701
701
  rel: "noopener noreferrer",
702
702
  href: "https://rebase.pro/docs/cloud/quickstart",
@@ -2329,6 +2329,53 @@ function sanitizeSqlIdentifier(name) {
2329
2329
  if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) throw new Error(`Invalid SQL identifier: "${name}". Only letters, digits, and underscores are allowed.`);
2330
2330
  return `"${name}"`;
2331
2331
  }
2332
+ /**
2333
+ * `pg_policies` reports the operation and the permissive flag in upper case;
2334
+ * `SecurityRule` names them in lower case. These two used to be `.toLowerCase()`
2335
+ * assigned straight into a `SecurityRule`, which typechecks only against a
2336
+ * `string` field — and this file declared its own local `SecurityRule` with
2337
+ * `operation?: string`, so it did. Against the real type it does not: an
2338
+ * unrecognised `cmd` would have been written into the collection as a policy
2339
+ * operation that compiles to nothing.
2340
+ */
2341
+ function toSecurityOperation(cmd) {
2342
+ switch (cmd) {
2343
+ case "SELECT": return "select";
2344
+ case "INSERT": return "insert";
2345
+ case "UPDATE": return "update";
2346
+ case "DELETE": return "delete";
2347
+ case "ALL": return "all";
2348
+ default: return;
2349
+ }
2350
+ }
2351
+ function toSecurityMode(permissive) {
2352
+ if (!permissive) return void 0;
2353
+ return permissive === "RESTRICTIVE" ? "restrictive" : "permissive";
2354
+ }
2355
+ /**
2356
+ * Build a {@link SecurityRule} from a `pg_policies` row.
2357
+ *
2358
+ * `SecurityRule` is a discriminated union and this is the part the local shadow
2359
+ * type flattened away: a raw-SQL rule *requires* `using`, so a policy with only
2360
+ * a `WITH CHECK` clause — every INSERT-only policy — is not one. It is a
2361
+ * roles-only rule carrying the check. Assembling the object field-by-field
2362
+ * against `operation?: string` accepted all of these and told the compiler
2363
+ * nothing.
2364
+ */
2365
+ function toSecurityRule(policy) {
2366
+ const base = {
2367
+ name: policy.policyname ?? "",
2368
+ operation: toSecurityOperation(policy.cmd),
2369
+ mode: toSecurityMode(policy.permissive),
2370
+ roles: policy.roles ? [...policy.roles] : void 0
2371
+ };
2372
+ if (policy.qual) return {
2373
+ ...base,
2374
+ using: policy.qual,
2375
+ withCheck: policy.with_check || void 0
2376
+ };
2377
+ return base;
2378
+ }
2332
2379
  function CollectionRLSTab() {
2333
2380
  const { values, setFieldValue } = useFormex();
2334
2381
  const [editingPolicy, setEditingPolicy] = useState(null);
@@ -2437,14 +2484,7 @@ function CollectionRLSTab() {
2437
2484
  ]);
2438
2485
  const unmappedPolicies = dbPolicies.filter((dp) => !generatedPolicyNames.has(dp.policyname));
2439
2486
  const handleSave = async (newPolicy) => {
2440
- const rule = {
2441
- name: newPolicy.policyname ?? "",
2442
- operation: newPolicy.cmd?.toLowerCase(),
2443
- mode: newPolicy.permissive?.toLowerCase(),
2444
- using: newPolicy.qual || void 0,
2445
- withCheck: newPolicy.with_check || void 0,
2446
- roles: newPolicy.roles
2447
- };
2487
+ const rule = toSecurityRule(newPolicy);
2448
2488
  let newRules;
2449
2489
  if (editingPolicy === "new") newRules = [...rules, rule];
2450
2490
  else newRules = rules.map((r) => r.name === editingPolicy.policyname ? rule : r);
@@ -2511,11 +2551,11 @@ function CollectionRLSTab() {
2511
2551
  size: "small",
2512
2552
  variant: "text",
2513
2553
  onClick: () => setEditingPolicy({
2514
- policyname: rule.name,
2554
+ policyname: rule.name ?? "",
2515
2555
  tablename: values.id || values.table || values.alias || "your_table",
2516
2556
  permissive: (rule.mode || "permissive").toUpperCase(),
2517
2557
  cmd: (rule.operation || "ALL").toUpperCase(),
2518
- roles: rule.roles || [],
2558
+ roles: [...rule.roles ?? []],
2519
2559
  qual: rule.using || null,
2520
2560
  with_check: rule.withCheck || null
2521
2561
  }),
@@ -2595,14 +2635,7 @@ function CollectionRLSTab() {
2595
2635
  variant: "outlined",
2596
2636
  color: "primary",
2597
2637
  onClick: () => {
2598
- const rule = {
2599
- name: dp.policyname,
2600
- operation: dp.cmd?.toLowerCase(),
2601
- mode: dp.permissive?.toLowerCase(),
2602
- using: dp.qual || void 0,
2603
- withCheck: dp.with_check || void 0,
2604
- roles: dp.roles
2605
- };
2638
+ const rule = toSecurityRule(dp);
2606
2639
  setFieldValue("securityRules", [...rules, rule]);
2607
2640
  },
2608
2641
  children: "Import to codebase"
@@ -2843,243 +2876,6 @@ function InlinePolicyEditor({ policy, table, availableRoles, rolesUnavailable, o
2843
2876
  ] });
2844
2877
  }
2845
2878
  //#endregion
2846
- //#region src/collection_editor/pgColumnToProperty.ts
2847
- /**
2848
- * Maps a PostgreSQL column data type to a Rebase property type.
2849
- */
2850
- function pgTypeToRebaseProperty(column) {
2851
- const { column_name, data_type, udt_name, is_nullable, column_default, enum_values } = column;
2852
- const required = is_nullable === "NO";
2853
- const prettifiedName = prettifyIdentifier(column_name);
2854
- const isAutoId = column_default != null && (column_default.includes("nextval") || column_default.includes("gen_random_uuid") || column_default.includes("uuid_generate") || column_default.includes("identity"));
2855
- if (data_type === "USER-DEFINED" && enum_values && enum_values.length > 0) return {
2856
- type: "string",
2857
- name: prettifiedName,
2858
- enum: enum_values.map((v) => ({
2859
- id: v,
2860
- label: prettifyIdentifier(v)
2861
- })),
2862
- validation: required ? { required: true } : void 0
2863
- };
2864
- const dt = data_type.toLowerCase();
2865
- switch (dt) {
2866
- case "character varying":
2867
- case "varchar":
2868
- case "text":
2869
- case "char":
2870
- case "character":
2871
- case "citext": {
2872
- let colType = "varchar";
2873
- if (dt === "text" || dt === "citext") colType = "text";
2874
- if (dt === "char" || dt === "character") colType = "char";
2875
- const prop = {
2876
- type: "string",
2877
- name: prettifiedName,
2878
- columnType: colType,
2879
- validation: required ? { required: true } : void 0
2880
- };
2881
- if (isAutoId) prop.isId = "manual";
2882
- return prop;
2883
- }
2884
- case "uuid": {
2885
- const prop = {
2886
- type: "string",
2887
- name: prettifiedName,
2888
- validation: required ? { required: true } : void 0
2889
- };
2890
- if (isAutoId) prop.isId = "uuid";
2891
- return prop;
2892
- }
2893
- case "integer":
2894
- case "bigint":
2895
- case "smallint": {
2896
- const prop = {
2897
- type: "number",
2898
- name: prettifiedName,
2899
- columnType: dt === "bigint" ? "bigint" : "integer",
2900
- validation: {
2901
- ...required ? { required: true } : {},
2902
- integer: true
2903
- }
2904
- };
2905
- if (isAutoId) prop.isId = "increment";
2906
- return prop;
2907
- }
2908
- case "serial":
2909
- case "bigserial":
2910
- case "smallserial": return {
2911
- type: "number",
2912
- name: prettifiedName,
2913
- columnType: dt === "bigserial" ? "bigserial" : "serial",
2914
- isId: "increment",
2915
- validation: {
2916
- ...required ? { required: true } : {},
2917
- integer: true
2918
- }
2919
- };
2920
- case "numeric":
2921
- case "decimal":
2922
- case "real":
2923
- case "double precision": {
2924
- let colType = "numeric";
2925
- if (dt === "real") colType = "real";
2926
- if (dt === "double precision") colType = "double precision";
2927
- return {
2928
- type: "number",
2929
- name: prettifiedName,
2930
- columnType: colType,
2931
- validation: required ? { required: true } : void 0
2932
- };
2933
- }
2934
- case "boolean": return {
2935
- type: "boolean",
2936
- name: prettifiedName,
2937
- validation: required ? { required: true } : void 0
2938
- };
2939
- case "timestamp with time zone":
2940
- case "timestamp without time zone":
2941
- case "timestamp":
2942
- case "timestamptz":
2943
- case "date":
2944
- case "time with time zone":
2945
- case "time without time zone":
2946
- case "time": {
2947
- let colType = "timestamp";
2948
- if (dt.startsWith("date")) colType = "date";
2949
- if (dt.startsWith("time ") || dt === "time") colType = "time";
2950
- return {
2951
- type: "date",
2952
- name: prettifiedName,
2953
- columnType: colType,
2954
- validation: required ? { required: true } : void 0
2955
- };
2956
- }
2957
- case "jsonb":
2958
- case "json": return {
2959
- type: "map",
2960
- name: prettifiedName,
2961
- columnType: dt === "jsonb" ? "jsonb" : "json",
2962
- keyValue: true,
2963
- properties: {}
2964
- };
2965
- case "array":
2966
- case "ARRAY": {
2967
- let innerType = "string";
2968
- let colType = void 0;
2969
- if (udt_name === "_text" || udt_name === "_varchar") {
2970
- innerType = "string";
2971
- colType = "text[]";
2972
- } else if (udt_name === "_int4" || udt_name === "_int2" || udt_name === "_int8") {
2973
- innerType = "number";
2974
- colType = "integer[]";
2975
- } else if (udt_name === "_bool") {
2976
- innerType = "boolean";
2977
- colType = "boolean[]";
2978
- } else if (udt_name === "_numeric") {
2979
- innerType = "number";
2980
- colType = "numeric[]";
2981
- }
2982
- return {
2983
- type: "array",
2984
- name: prettifiedName,
2985
- columnType: colType,
2986
- of: { type: innerType }
2987
- };
2988
- }
2989
- default: return {
2990
- type: "string",
2991
- name: prettifiedName,
2992
- validation: required ? { required: true } : void 0
2993
- };
2994
- }
2995
- }
2996
- /**
2997
- * Builds a partial AdminCollection from PostgreSQL table metadata.
2998
- * This is used when creating a new collection from an existing database table.
2999
- */
3000
- function buildCollectionFromTableMetadata(tableName, metadata) {
3001
- const properties = {};
3002
- const propertiesOrder = [];
3003
- const relations = [];
3004
- const securityRules = [];
3005
- for (const column of metadata.columns) {
3006
- const property = pgTypeToRebaseProperty(column);
3007
- if (property) {
3008
- const propRecord = property;
3009
- Object.keys(propRecord).forEach((key) => propRecord[key] === void 0 && delete propRecord[key]);
3010
- properties[column.column_name] = property;
3011
- propertiesOrder.push(column.column_name);
3012
- }
3013
- }
3014
- if (metadata.foreignKeys) for (const fk of metadata.foreignKeys) {
3015
- const relName = fk.column_name.endsWith("_id") ? fk.column_name.substring(0, fk.column_name.length - 3) : fk.column_name;
3016
- relations.push({
3017
- id: fk.column_name,
3018
- relationName: relName,
3019
- target: fk.foreign_table_name,
3020
- cardinality: "one",
3021
- direction: "owning",
3022
- localKey: fk.column_name
3023
- });
3024
- }
3025
- if (metadata.junctions) for (const junction of metadata.junctions) {
3026
- const relName = junction.target_table_name;
3027
- relations.push({
3028
- id: junction.target_table_name + "_relation",
3029
- relationName: relName,
3030
- target: junction.target_table_name,
3031
- cardinality: "many",
3032
- direction: "owning",
3033
- through: {
3034
- table: junction.junction_table_name,
3035
- sourceColumn: junction.source_column_name,
3036
- targetColumn: junction.target_column_name
3037
- }
3038
- });
3039
- }
3040
- if (metadata.policies) for (const policy of metadata.policies) {
3041
- let operations = [];
3042
- switch (policy.cmd) {
3043
- case "ALL":
3044
- operations = [
3045
- "read",
3046
- "create",
3047
- "update",
3048
- "delete"
3049
- ];
3050
- break;
3051
- case "SELECT":
3052
- operations = ["read"];
3053
- break;
3054
- case "INSERT":
3055
- operations = ["create"];
3056
- break;
3057
- case "UPDATE":
3058
- operations = ["update"];
3059
- break;
3060
- case "DELETE":
3061
- operations = ["delete"];
3062
- break;
3063
- }
3064
- securityRules.push({
3065
- name: policy.policy_name,
3066
- operations,
3067
- roles: policy.roles ?? [],
3068
- qual: policy.qual,
3069
- with_check: policy.with_check
3070
- });
3071
- }
3072
- return {
3073
- name: prettifyIdentifier(tableName),
3074
- slug: tableName,
3075
- table: tableName,
3076
- properties,
3077
- propertiesOrder,
3078
- ...relations.length > 0 ? { relations } : {},
3079
- ...securityRules.length > 0 ? { securityRules } : {}
3080
- };
3081
- }
3082
- //#endregion
3083
2879
  //#region src/collection_editor/ui/collection_editor/CollectionEditorDialog.tsx
3084
2880
  var CollectionEditorDialog_exports = /* @__PURE__ */ __exportAll({
3085
2881
  CollectionEditor: () => CollectionEditor,
@@ -3741,4 +3537,4 @@ var validateId = (value, isNewCollection, existingPaths, existingIds) => {
3741
3537
  //#endregion
3742
3538
  export { CollectionEditorDialog as n, CollectionEditorDialog_exports as r, CollectionEditor as t };
3743
3539
 
3744
- //# sourceMappingURL=CollectionEditorDialog-o7F_zbGY.js.map
3540
+ //# sourceMappingURL=CollectionEditorDialog-Dpc75wIZ.js.map