@rebasepro/common 0.0.1-canary.ca2cb6e → 0.0.1-canary.cbdd980
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/README.md +178 -110
- package/dist/index.es.js +23 -18
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +24 -18
- package/dist/index.umd.js.map +1 -1
- package/package.json +4 -7
- package/src/collections/CollectionRegistry.ts +16 -14
- package/src/util/conditions.ts +8 -5
- package/src/util/entities.ts +3 -3
- package/src/util/references.ts +1 -1
- package/src/util/relations.ts +5 -5
- package/src/util/resolutions.ts +4 -4
package/README.md
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
<p align="center">
|
|
2
|
-
<img src="https://rebase.pro/img/dark_mode.webp" alt="Intro video" style="max-width: 100%;"/>
|
|
3
|
-
</p>
|
|
4
|
-
|
|
5
1
|
<p align="center">
|
|
6
2
|
<a href="https://rebase.pro">
|
|
7
3
|
<img src="https://rebase.pro/img/logo_small.png" width="240px" alt="Rebase logo" />
|
|
@@ -9,166 +5,238 @@
|
|
|
9
5
|
</p>
|
|
10
6
|
|
|
11
7
|
<h1 align="center">Rebase</h1>
|
|
12
|
-
<h3 align="center">
|
|
13
|
-
<p align="center"
|
|
8
|
+
<h3 align="center">The Open-Source Headless CMS & Admin Panel for Postgres</h3>
|
|
9
|
+
<p align="center">
|
|
10
|
+
<strong>Ship production-ready backends and radically extensible back-office apps in minutes.</strong><br/>
|
|
11
|
+
Own your data, own your code. The absolute easiest way to build on PostgreSQL.
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
<p align="center">
|
|
15
|
+
<a href="https://demo.rebase.pro">Live Demo</a> •
|
|
16
|
+
<a href="https://rebase.pro/docs">Documentation</a> •
|
|
17
|
+
<a href="https://rebase.pro/features">Features</a> •
|
|
18
|
+
<a href="https://github.com/rebasepro/rebase">GitHub</a> •
|
|
19
|
+
<a href="https://discord.gg/fxy7xsQm3m">Discord</a>
|
|
20
|
+
</p>
|
|
14
21
|
|
|
15
|
-
<
|
|
22
|
+
<p align="center">
|
|
23
|
+
<a href="https://www.npmjs.com/package/@rebasepro/core"><img src="https://img.shields.io/npm/v/@rebasepro/core.svg?style=flat-square&color=orange" alt="NPM Version" /></a>
|
|
24
|
+
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/license-MIT-purple.svg?style=flat-square" alt="License: MIT" /></a>
|
|
25
|
+
<a href="https://www.npmjs.com/package/@rebasepro/core"><img src="https://img.shields.io/npm/dw/@rebasepro/core?style=flat-square&color=blue" alt="NPM Downloads" /></a>
|
|
26
|
+
<a href="https://discord.gg/fxy7xsQm3m"><img src="https://img.shields.io/discord/1013768502458470442?style=flat-square&logo=discord&logoColor=white&label=Discord" alt="Discord" /></a>
|
|
27
|
+
</p>
|
|
28
|
+
|
|
29
|
+
<br/>
|
|
30
|
+
|
|
31
|
+
<p align="center">
|
|
32
|
+
<img src="https://rebase.pro/img/demo_products.png" width="800px" alt="Rebase Dashboard" />
|
|
33
|
+
</p>
|
|
16
34
|
|
|
35
|
+
---
|
|
17
36
|
|
|
18
|
-
|
|
37
|
+
## What is Rebase?
|
|
19
38
|
|
|
20
|
-
|
|
21
|
-
that seamlessly integrates with **Firebase and Firestore** by default, but is
|
|
22
|
-
also
|
|
23
|
-
compatible with any backend.
|
|
39
|
+
Rebase is a **developer-first**, open-source headless CMS and admin panel framework built with **React** and **TypeScript**. It gives you a complete backend-as-a-service layer on top of PostgreSQL — including authentication, S3-compatible storage, a full admin UI, and auto-generated APIs — while letting you extend every layer with custom React components, serverless functions, and scripts.
|
|
24
40
|
|
|
25
|
-
|
|
26
|
-
simple
|
|
27
|
-
to set up for standard cases and easy to extend and customize for more specific
|
|
28
|
-
needs.
|
|
41
|
+
### ✨ Key Highlights
|
|
29
42
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
43
|
+
- 🔓 **No Vendor Lock-in** — Self-host anywhere. Full control over your infrastructure, code, and database.
|
|
44
|
+
- ⚡ **Instant Setup** — `npx @rebasepro/cli init` scaffolds a production-ready project in seconds.
|
|
45
|
+
- 🗄️ **PostgreSQL First** — First-class Postgres support with Drizzle ORM, schema introspection, and automatic migrations.
|
|
46
|
+
- 🧩 **Radical Extensibility** — Not constrained to pre-built widgets. If you can build it in React, you can build it in Rebase.
|
|
47
|
+
- 🎨 **Premium UI** — Fast, accessible design system built on Tailwind CSS v4 and Radix UI.
|
|
48
|
+
- 🤖 **AI-Ready** — MCP server for AI-assisted database management, plus data enhancement and insights plugins.
|
|
34
49
|
|
|
35
|
-
|
|
36
|
-
out-of-the-box experience for any project.
|
|
50
|
+
---
|
|
37
51
|
|
|
38
|
-
|
|
52
|
+
## ⚡ Quick Start
|
|
39
53
|
|
|
40
|
-
Rebase
|
|
54
|
+
Scaffold a complete, self-hosted Rebase application connected to your database:
|
|
41
55
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
- React + React Router 6
|
|
56
|
+
```bash
|
|
57
|
+
npx @rebasepro/cli init my-rebase-app
|
|
58
|
+
```
|
|
46
59
|
|
|
47
|
-
|
|
60
|
+
Configure your database in `.env`, then start everything:
|
|
48
61
|
|
|
49
|
-
|
|
50
|
-
|
|
62
|
+
```bash
|
|
63
|
+
cd my-rebase-app
|
|
64
|
+
npm run dev
|
|
65
|
+
```
|
|
51
66
|
|
|
52
|
-
|
|
67
|
+
Your admin panel is running at `http://localhost:5173` and the API at `http://localhost:3001`.
|
|
53
68
|
|
|
54
|
-
|
|
69
|
+
---
|
|
55
70
|
|
|
56
|
-
|
|
71
|
+
## Features
|
|
57
72
|
|
|
58
|
-
|
|
73
|
+
### 🏓 Full Admin Panel & CMS
|
|
59
74
|
|
|
60
|
-
|
|
75
|
+
An incredibly fast, windowed spreadsheet view to manage your database with inline editing, real-time updates, filtering, sorting, and text search. Switch between multiple view modes:
|
|
61
76
|
|
|
62
|
-
|
|
77
|
+
- **Spreadsheet table** — Inline editing, column reordering, drag-and-drop
|
|
78
|
+
- **Card grid** — Visual overview with image previews
|
|
79
|
+
- **List view** — Compact, scannable layout
|
|
80
|
+
- **Custom views** — Build any React component as a collection view
|
|
63
81
|
|
|
64
|
-
|
|
82
|
+
### 🔒 Typed Schema & Database Migrations
|
|
65
83
|
|
|
66
|
-
|
|
84
|
+
Define your data models using pure TypeScript collections. Rebase automatically generates your Drizzle ORM schema, handles PostgreSQL migrations, and keeps your live database perfectly in sync using built-in tooling like `rebase doctor`.
|
|
85
|
+
|
|
86
|
+
### 🔐 Authentication & Access Control
|
|
87
|
+
|
|
88
|
+
Built-in authentication with multiple providers:
|
|
89
|
+
|
|
90
|
+
- **Email/Password** — With password reset flow
|
|
91
|
+
- **Google OAuth** — One-click sign-in
|
|
92
|
+
- **Anonymous** — For guest access
|
|
93
|
+
|
|
94
|
+
Granular **role-based access control (RBAC)** with customizable permissions per collection, field, and action.
|
|
95
|
+
|
|
96
|
+
### 📦 S3-Compatible Storage
|
|
97
|
+
|
|
98
|
+
Native S3-compatible file storage with:
|
|
99
|
+
|
|
100
|
+
- Drag-and-drop uploads with progress tracking
|
|
101
|
+
- Automatic image resizing and optimization
|
|
102
|
+
- File metadata management
|
|
103
|
+
- Storage browser in Studio
|
|
104
|
+
|
|
105
|
+
### 🛠️ Studio — Developer Toolbox
|
|
106
|
+
|
|
107
|
+
A full developer environment built into the admin panel:
|
|
108
|
+
|
|
109
|
+
| Tool | Description |
|
|
110
|
+
|---|---|
|
|
111
|
+
| **SQL Editor** | Write and execute SQL queries directly against your database with schema-aware autocomplete |
|
|
112
|
+
| **RLS Policy Editor** | Visual editor for PostgreSQL Row-Level Security policies |
|
|
113
|
+
| **Schema Visualizer** | Interactive ER diagram of your database with relationship mapping |
|
|
114
|
+
| **JS/TS Editor** | In-browser code editor for scripts and functions |
|
|
115
|
+
| **API Explorer** | Browse and test your auto-generated REST API endpoints |
|
|
116
|
+
| **Cron Jobs** | Schedule and monitor recurring tasks |
|
|
117
|
+
| **Storage Browser** | Browse and manage files in your S3-compatible storage |
|
|
118
|
+
|
|
119
|
+
### ⚡ Extensible API & Edge Functions
|
|
120
|
+
|
|
121
|
+
Drop custom Hono routes or scheduled tasks into the `functions/` and `crons/` directories. Rebase auto-loads them with database access and JWT authentication middleware injected automatically.
|
|
122
|
+
|
|
123
|
+
### 🧬 SDK Generator
|
|
124
|
+
|
|
125
|
+
Auto-generate fully typed **TypeScript SDKs** from your collection definitions. Use them in any frontend, script, or service to interact with your Rebase backend with complete type safety.
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
npx @rebasepro/cli generate-sdk
|
|
129
|
+
```
|
|
67
130
|
|
|
68
|
-
|
|
69
|
-
to build a CMS/admin tool while offering an excellent data editing experience
|
|
70
|
-
and a user-friendly interface for marketers and content managers.
|
|
131
|
+
### 🤖 MCP Server
|
|
71
132
|
|
|
72
|
-
|
|
133
|
+
A built-in **Model Context Protocol** server that enables AI assistants to:
|
|
73
134
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
135
|
+
- Query and manage your database schema
|
|
136
|
+
- Create, read, update, and delete documents
|
|
137
|
+
- Manage users and roles
|
|
138
|
+
- Introspect your data model
|
|
77
139
|
|
|
78
|
-
|
|
79
|
-
constant updates. It also supports **text search** (through an external provider
|
|
80
|
-
like Algolia, if using Firestore), **filtering and sorting**, and **exporting**
|
|
81
|
-
data.
|
|
140
|
+
### 🔍 Schema Inference & Introspection
|
|
82
141
|
|
|
83
|
-
|
|
142
|
+
Point Rebase at an existing PostgreSQL database and automatically generate collection definitions from your tables — including types, relations, validation constraints, and more.
|
|
84
143
|
|
|
85
|
-
|
|
144
|
+
### 📥📤 Import & Export
|
|
86
145
|
|
|
87
|
-
|
|
88
|
-
navigating through **subcollections** and accessing custom views (such as custom
|
|
89
|
-
forms or blog previews). This functionality can also be accessed
|
|
90
|
-
programmatically using the `useSideEntityController` hook.
|
|
146
|
+
Import data from **CSV, JSON, and Excel** with an intuitive field mapper. Export your data in multiple formats with configurable column selection.
|
|
91
147
|
|
|
92
|
-
|
|
93
|
-
validation options. The components have been carefully designed for an
|
|
94
|
-
outstanding user experience, including advanced features like **references** to
|
|
95
|
-
other collections, **markdown**, and **array reordering**.
|
|
148
|
+
### 🧩 Plugins
|
|
96
149
|
|
|
97
|
-
|
|
98
|
-
component.
|
|
150
|
+
Extend the admin experience with first-party plugins:
|
|
99
151
|
|
|
100
|
-
|
|
101
|
-
|
|
152
|
+
- **Data Enhancement** — AI-powered field suggestions and auto-fill
|
|
153
|
+
- **Insights** — Analytics dashboards and usage metrics
|
|
102
154
|
|
|
103
|
-
###
|
|
155
|
+
### 📜 Standalone Scripting
|
|
104
156
|
|
|
105
|
-
|
|
106
|
-
delete) they can perform based on your role system. You can even configure this
|
|
107
|
-
on a per-entity or collection level.
|
|
157
|
+
Write standalone data manipulation scripts that connect directly to your running backend using the `@rebasepro/client` SDK. The CLI persists the dev server URL to `.rebase-dev-url` for zero-config local development.
|
|
108
158
|
|
|
109
|
-
|
|
110
|
-
implement your own.
|
|
159
|
+
### 🧩 Custom Views & React Extensibility
|
|
111
160
|
|
|
112
|
-
|
|
161
|
+
Build entirely custom views — dashboards, previews, charts — and drop them into the main navigation or as entity-level tabs. Use built-in hooks to interact with Rebase's internal state.
|
|
113
162
|
|
|
114
|
-
|
|
115
|
-
integrated reference fields and shortcuts.
|
|
163
|
+
---
|
|
116
164
|
|
|
117
|
-
|
|
118
|
-
collection/document/collection model.
|
|
165
|
+
## 🛠️ Core Technologies
|
|
119
166
|
|
|
120
|
-
|
|
167
|
+
Built entirely on modern, battle-tested web standards:
|
|
121
168
|
|
|
122
|
-
|
|
123
|
-
|
|
169
|
+
| Technology | What we use it for |
|
|
170
|
+
|---|---|
|
|
171
|
+
| 💙 **TypeScript 5.x** | End-to-end type safety |
|
|
172
|
+
| ⚛️ **React 19** | Component-driven UI |
|
|
173
|
+
| 🌊 **Tailwind CSS v4** | Utility-first styling |
|
|
174
|
+
| 🔌 **WebSockets** | Real-time synchronization |
|
|
175
|
+
| 🗄️ **Drizzle ORM** | Type-safe SQL migrations and queries |
|
|
176
|
+
| 🧱 **Radix UI** | Accessible UI primitives |
|
|
177
|
+
| 📝 **TipTap v3** | Rich text editing |
|
|
178
|
+
| 🌐 **Hono** | Ultrafast HTTP server framework |
|
|
124
179
|
|
|
125
|
-
|
|
126
|
-
updated in any open form view as long as it hasn't been touched by the user.
|
|
127
|
-
This enables advanced cases where a Cloud Function is triggered after saving an
|
|
128
|
-
entity, modifying some values, and requiring real-time updates.
|
|
180
|
+
---
|
|
129
181
|
|
|
130
|
-
|
|
182
|
+
## 📦 Packages
|
|
131
183
|
|
|
132
|
-
Rebase
|
|
133
|
-
specific fields for handling single and multiple file uploads, as well as
|
|
134
|
-
reordering.
|
|
184
|
+
Rebase is structured as a modular monorepo — install only the layers you need:
|
|
135
185
|
|
|
136
|
-
|
|
186
|
+
| Package | Description |
|
|
187
|
+
|---|---|
|
|
188
|
+
| `@rebasepro/types` | Core TypeScript type definitions |
|
|
189
|
+
| `@rebasepro/utils` | Shared utility functions |
|
|
190
|
+
| `@rebasepro/common` | Common modules shared across packages |
|
|
191
|
+
| `@rebasepro/formex` | Lightweight form management library |
|
|
192
|
+
| `@rebasepro/ui` | Standalone React component library (Tailwind + Radix) |
|
|
193
|
+
| `@rebasepro/core` | Core CMS logic and controllers |
|
|
194
|
+
| `@rebasepro/client` | Client-side data access layer |
|
|
195
|
+
| `@rebasepro/client-postgresql` | PostgreSQL client adapter |
|
|
196
|
+
| `@rebasepro/client-firebase` | Firebase/Firestore client adapter |
|
|
197
|
+
| `@rebasepro/server-core` | Server framework and middleware (Hono) |
|
|
198
|
+
| `@rebasepro/server-postgresql` | PostgreSQL server adapter with Drizzle |
|
|
199
|
+
| `@rebasepro/server-mongodb` | MongoDB server adapter |
|
|
200
|
+
| `@rebasepro/auth` | Authentication controllers and login views |
|
|
201
|
+
| `@rebasepro/admin` | Full admin panel interface |
|
|
202
|
+
| `@rebasepro/studio` | SQL editor, RLS editor, schema visualizer, API explorer |
|
|
203
|
+
| `@rebasepro/cli` | CLI for project scaffolding and management |
|
|
204
|
+
| `@rebasepro/sdk-generator` | TypeScript SDK code generation |
|
|
205
|
+
| `@rebasepro/mcp-server` | MCP server for AI integrations |
|
|
206
|
+
| `@rebasepro/schema-inference` | Database schema introspection and inference |
|
|
207
|
+
| `@rebasepro/plugin-data-enhancement` | AI-powered data enhancement plugin |
|
|
208
|
+
| `@rebasepro/plugin-insights` | Analytics and insights plugin |
|
|
137
209
|
|
|
138
|
-
|
|
210
|
+
---
|
|
139
211
|
|
|
140
|
-
|
|
141
|
-
[`example`](https://github.com/rebasepro/rebase/tree/master/example). It includes
|
|
142
|
-
every feature provided by this CMS.
|
|
212
|
+
## 🎨 Standalone UI Library
|
|
143
213
|
|
|
144
|
-
|
|
145
|
-
use it as it is, without linking it to the library source code. More details in
|
|
146
|
-
its README
|
|
214
|
+
Rebase exposes its design system as a completely independent library. Fully typed, accessible, and customizable via Tailwind CSS v4:
|
|
147
215
|
|
|
148
|
-
|
|
216
|
+
```bash
|
|
217
|
+
npm install @rebasepro/ui
|
|
218
|
+
```
|
|
149
219
|
|
|
150
|
-
|
|
220
|
+
---
|
|
151
221
|
|
|
152
|
-
|
|
153
|
-
happy to help!
|
|
154
|
-
`hello@rebase.pro`
|
|
222
|
+
## Demo
|
|
155
223
|
|
|
156
|
-
|
|
224
|
+
Explore a live interactive sandbox with all features — data resets periodically:
|
|
157
225
|
|
|
158
|
-
|
|
226
|
+
**👉 [demo.rebase.pro](https://demo.rebase.pro)**
|
|
159
227
|
|
|
160
|
-
|
|
161
|
-
There is an example project in the folder `example`.
|
|
228
|
+
---
|
|
162
229
|
|
|
163
|
-
|
|
164
|
-
called `firebase_config.ts`
|
|
165
|
-
in `example/src`.
|
|
230
|
+
## Support & Community
|
|
166
231
|
|
|
167
|
-
|
|
168
|
-
|
|
232
|
+
- 📖 [Documentation](https://rebase.pro/docs)
|
|
233
|
+
- 💬 [Discord Community](https://discord.gg/fxy7xsQm3m)
|
|
234
|
+
- 🐛 [GitHub Issues](https://github.com/rebasepro/rebase/issues)
|
|
235
|
+
- 📝 [Changelog](./CHANGELOG.md)
|
|
169
236
|
|
|
170
|
-
|
|
237
|
+
---
|
|
171
238
|
|
|
172
239
|
## License
|
|
173
240
|
|
|
174
|
-
MIT
|
|
241
|
+
Rebase is open-source and licensed under the **MIT License**.
|
|
242
|
+
See the full [License](https://github.com/rebasepro/rebase/blob/main/LICENSE) for details.
|
package/dist/index.es.js
CHANGED
|
@@ -1,22 +1,21 @@
|
|
|
1
1
|
import { EntityReference, EntityRelation, getDataSourceCapabilities } from "@rebasepro/types";
|
|
2
|
-
import { mergeDeep, getIn as getIn$1, isDefaultFieldConfigId, randomString, toSnakeCase, generateForeignKeyName, removeFunctions } from "@rebasepro/utils";
|
|
2
|
+
import { mergeDeep, getIn as getIn$1, isDefaultFieldConfigId, randomString, toSnakeCase, generateForeignKeyName, removeFunctions, deepClone } from "@rebasepro/utils";
|
|
3
3
|
import jsonLogic from "json-logic-js";
|
|
4
4
|
import { deepEqual } from "fast-equals";
|
|
5
|
-
import cloneDeep from "lodash/cloneDeep.js";
|
|
6
5
|
const DEFAULT_ONE_OF_TYPE = "type";
|
|
7
6
|
const DEFAULT_ONE_OF_VALUE = "value";
|
|
8
7
|
function isReadOnly(property) {
|
|
9
|
-
if (property.readOnly) return true;
|
|
8
|
+
if (property.ui?.readOnly) return true;
|
|
10
9
|
if (property.type === "date") {
|
|
11
10
|
if (property.autoValue) return true;
|
|
12
11
|
}
|
|
13
12
|
if (property.type === "reference") {
|
|
14
|
-
return !property.path && !("Field" in property && property.Field);
|
|
13
|
+
return !property.path && !("Field" in (property.ui || {}) && property.ui?.Field);
|
|
15
14
|
}
|
|
16
15
|
return false;
|
|
17
16
|
}
|
|
18
17
|
function isHidden(property) {
|
|
19
|
-
return typeof property.disabled === "object" && Boolean(property.disabled.hidden);
|
|
18
|
+
return typeof property.ui?.disabled === "object" && Boolean(property.ui?.disabled.hidden);
|
|
20
19
|
}
|
|
21
20
|
function isPropertyBuilder(property) {
|
|
22
21
|
return typeof property?.dynamicProps === "function";
|
|
@@ -500,7 +499,7 @@ function resolveArrayProperties({
|
|
|
500
499
|
});
|
|
501
500
|
}).filter((e) => Boolean(e)) : [];
|
|
502
501
|
return resolvedProperties;
|
|
503
|
-
} else if (!("Field" in property && property.Field)) {
|
|
502
|
+
} else if (!("Field" in (property.ui || {}) && property.ui?.Field)) {
|
|
504
503
|
throw Error(`The array property (${propertyKey}) needs to declare an 'of' or a 'oneOf' property, or provide a custom \`Field\` component`);
|
|
505
504
|
} else {
|
|
506
505
|
return [];
|
|
@@ -730,7 +729,7 @@ function getEntityImagePreviewPropertyKey(collection) {
|
|
|
730
729
|
}
|
|
731
730
|
for (const key in collection.properties) {
|
|
732
731
|
const property = collection.properties[key];
|
|
733
|
-
if (property.type === "string" && property.url === "image") {
|
|
732
|
+
if (property.type === "string" && property.ui?.url === "image") {
|
|
734
733
|
return key;
|
|
735
734
|
}
|
|
736
735
|
}
|
|
@@ -1453,7 +1452,8 @@ function applyPropertyConditions(property, context) {
|
|
|
1453
1452
|
if (conditions.disabled) {
|
|
1454
1453
|
const isDisabled = evaluateCondition(conditions.disabled, context);
|
|
1455
1454
|
if (isDisabled) {
|
|
1456
|
-
result.
|
|
1455
|
+
result.ui = result.ui || {};
|
|
1456
|
+
result.ui.disabled = {
|
|
1457
1457
|
clearOnDisabled: conditions.clearOnDisabled ?? false,
|
|
1458
1458
|
disabledMessage: conditions.disabledMessage,
|
|
1459
1459
|
hidden: false
|
|
@@ -1463,8 +1463,9 @@ function applyPropertyConditions(property, context) {
|
|
|
1463
1463
|
if (conditions.hidden) {
|
|
1464
1464
|
const isHidden2 = evaluateCondition(conditions.hidden, context);
|
|
1465
1465
|
if (isHidden2) {
|
|
1466
|
-
result.
|
|
1467
|
-
|
|
1466
|
+
result.ui = result.ui || {};
|
|
1467
|
+
result.ui.disabled = {
|
|
1468
|
+
...typeof result.ui?.disabled === "object" ? result.ui.disabled : {},
|
|
1468
1469
|
hidden: true,
|
|
1469
1470
|
clearOnDisabled: conditions.clearOnDisabled ?? false
|
|
1470
1471
|
};
|
|
@@ -1473,7 +1474,8 @@ function applyPropertyConditions(property, context) {
|
|
|
1473
1474
|
if (conditions.readOnly) {
|
|
1474
1475
|
const isReadOnly2 = evaluateCondition(conditions.readOnly, context);
|
|
1475
1476
|
if (isReadOnly2) {
|
|
1476
|
-
result.
|
|
1477
|
+
result.ui = result.ui || {};
|
|
1478
|
+
result.ui.readOnly = true;
|
|
1477
1479
|
}
|
|
1478
1480
|
}
|
|
1479
1481
|
if (conditions.required !== void 0) {
|
|
@@ -1495,7 +1497,7 @@ function applyPropertyConditions(property, context) {
|
|
|
1495
1497
|
result.path = evaluateCondition(conditions.referencePath, context);
|
|
1496
1498
|
}
|
|
1497
1499
|
if (conditions.referenceFilter) {
|
|
1498
|
-
result.
|
|
1500
|
+
result.fixedFilter = evaluateCondition(conditions.referenceFilter, context);
|
|
1499
1501
|
}
|
|
1500
1502
|
}
|
|
1501
1503
|
if (result.type === "array") {
|
|
@@ -1599,7 +1601,7 @@ class CollectionRegistry {
|
|
|
1599
1601
|
...c
|
|
1600
1602
|
}));
|
|
1601
1603
|
normalizedCollections.forEach((c, index) => {
|
|
1602
|
-
const raw =
|
|
1604
|
+
const raw = deepClone(collections[index]);
|
|
1603
1605
|
this.rootCollections.push(c);
|
|
1604
1606
|
this.rawRootCollections.push(raw);
|
|
1605
1607
|
const normalized = this.normalizeCollection(c);
|
|
@@ -1619,7 +1621,7 @@ class CollectionRegistry {
|
|
|
1619
1621
|
if (!subCollection) return;
|
|
1620
1622
|
this._registerRecursively(this.normalizeCollection({
|
|
1621
1623
|
...subCollection
|
|
1622
|
-
}),
|
|
1624
|
+
}), deepClone(subCollection));
|
|
1623
1625
|
});
|
|
1624
1626
|
}
|
|
1625
1627
|
});
|
|
@@ -1627,7 +1629,7 @@ class CollectionRegistry {
|
|
|
1627
1629
|
return true;
|
|
1628
1630
|
}
|
|
1629
1631
|
register(collection, rawCollection) {
|
|
1630
|
-
const raw = rawCollection ?
|
|
1632
|
+
const raw = rawCollection ? deepClone(rawCollection) : deepClone(collection);
|
|
1631
1633
|
this.rootCollections.push(collection);
|
|
1632
1634
|
this.rawRootCollections.push(raw);
|
|
1633
1635
|
this._registerRecursively(collection, raw);
|
|
@@ -1651,7 +1653,7 @@ class CollectionRegistry {
|
|
|
1651
1653
|
if (!subCollection) return;
|
|
1652
1654
|
this._registerRecursively(this.normalizeCollection({
|
|
1653
1655
|
...subCollection
|
|
1654
|
-
}),
|
|
1656
|
+
}), deepClone(subCollection));
|
|
1655
1657
|
});
|
|
1656
1658
|
}
|
|
1657
1659
|
}
|
|
@@ -1823,7 +1825,10 @@ class CollectionRegistry {
|
|
|
1823
1825
|
if (!relation) {
|
|
1824
1826
|
throw new Error(`Relation '${relationKey}' not found in collection '${currentCollection.slug}'`);
|
|
1825
1827
|
}
|
|
1826
|
-
|
|
1828
|
+
const target = relation.target();
|
|
1829
|
+
const targetRelationKey = relation.relationName || target.slug;
|
|
1830
|
+
const targetSlug = relation.overrides?.slug ?? targetRelationKey;
|
|
1831
|
+
currentCollection = this.get(targetSlug) || this.normalizeCollection(target);
|
|
1827
1832
|
if (i + 1 < pathSegments.length) ;
|
|
1828
1833
|
}
|
|
1829
1834
|
return currentCollection;
|
|
@@ -1872,7 +1877,7 @@ class CollectionRegistry {
|
|
|
1872
1877
|
if (!subcollection) {
|
|
1873
1878
|
throw new Error(`Subcollection '${subcollectionSlug}' not found in ${currentCollection.slug}`);
|
|
1874
1879
|
}
|
|
1875
|
-
currentCollection = subcollection;
|
|
1880
|
+
currentCollection = this.get(subcollection.slug) || this.normalizeCollection(subcollection);
|
|
1876
1881
|
collections.push(currentCollection);
|
|
1877
1882
|
}
|
|
1878
1883
|
}
|