@metaobjectsdev/sdk 0.11.0-rc.1 → 0.11.1-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -214,7 +214,7 @@ The `[]` key-suffix declares an array field: `field.long[]: weekIds` lowers to
214
214
  | Subtype | Purpose | Key attrs |
215
215
  |---|---|---|
216
216
  | `identity.primary` | the PK field(s) | `@fields`, `@generation` |
217
- | `identity.secondary` | a unique secondary index | `@fields` |
217
+ | `identity.secondary` | a unique secondary index | `@fields` (or `@expr` for a functional index) |
218
218
  | `identity.reference` | an inbound FK from this entity to another | `@fields`, `@references`, `@enforce` |
219
219
 
220
220
  `@generation` on a primary controls value generation (e.g. `increment`).
@@ -231,9 +231,21 @@ name resolves within the current package. The FK target must be an entity with a
231
231
  single-column primary key (the FK points at that PK); a target with a composite
232
232
  PK needs the explicit dotted form `@references: "pkg::Target.fieldA,fieldB"`.
233
233
 
234
+ **A dangling reference fails the load (0.11.0+).** An unresolved
235
+ `identity.reference.@references` raises `ERR_INVALID_REFERENCE` and an unresolved
236
+ `relationship.@objectRef` raises `ERR_INVALID_RELATIONSHIP` — the target entity must
237
+ exist (previously such references loaded silently). So every `@references` /
238
+ `@objectRef` you author must name a real entity.
239
+
240
+ A `identity.secondary` can index an **expression** instead of plain columns: use
241
+ `@expr` (e.g. `"lower(email)"`) in place of `@fields`, optionally with `@using` (the
242
+ index method — `gin` / `gist` / `hash`; default `btree`) and `@where` (a partial-index
243
+ predicate).
244
+
234
245
  ```json
235
246
  { "identity.primary": { "name": "id", "@fields": ["id"], "@generation": "increment" } }
236
247
  { "identity.secondary": { "name": "byEmail", "@fields": ["email"] } }
248
+ { "identity.secondary": { "name": "byEmailCI", "@expr": "lower(email)" } }
237
249
  { "identity.reference": { "name": "fkAuthor", "@fields": ["authorId"], "@references": "Author", "@enforce": true } }
238
250
  ```
239
251
 
@@ -266,6 +278,28 @@ makes the metadata declare `CASCADE` where the DB has `NO ACTION` — a perpetua
266
278
  "@cardinality": "one", "@onDelete": "no-action", "@onUpdate": "no-action" } }
267
279
  ```
268
280
 
281
+ ## Validators — cross-field rules
282
+
283
+ Entity-scoped `validator.*` children declare invariants that reference sibling fields
284
+ **by name** (the same name-reference pattern as `identity.*`). The backend derives the
285
+ enforcement (a CHECK constraint / cross-field assertion) — no raw expression is stored.
286
+
287
+ | Subtype | Rule | Key attrs |
288
+ |---|---|---|
289
+ | `validator.comparison` | two fields stand in a relational order (`@left @op @right`) | `@left`, `@op` (`gt`/`gte`/`lt`/`lte`/`ne`/`eq`), `@right` |
290
+ | `validator.requiredWhen` | `@field` is required when `@when` equals `@equals` | `@field`, `@when`, `@equals` |
291
+ | `validator.presentIff` | `@field` is present **iff** `@when` equals `@equals` (biconditional) | `@field`, `@when`, `@equals` |
292
+ | `validator.atLeastOne` | at least one of `@fields` (2+) is present | `@fields` |
293
+
294
+ ```json
295
+ { "validator.comparison": { "name": "hpInRange", "@left": "currentHp", "@op": "lte", "@right": "maxHp" } }
296
+ { "validator.requiredWhen": { "name": "reasonIfRejected", "@field": "rejectReason", "@when": "status", "@equals": "rejected" } }
297
+ { "validator.presentIff": { "name": "usedAtWhenUsed", "@field": "usedAt", "@when": "isUsed", "@equals": "true" } }
298
+ { "validator.atLeastOne": { "name": "emailOrPhone", "@fields": ["email", "phone"] } }
299
+ ```
300
+
301
+ These are children of `object.entity`, alongside its fields and identities.
302
+
269
303
  ## Sources — `source.rdb` + `@kind`
270
304
 
271
305
  `source.rdb` declares where an entity's data lives. Read-only-ness derives from
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metaobjectsdev/sdk",
3
- "version": "0.11.0-rc.1",
3
+ "version": "0.11.1-rc.1",
4
4
  "description": "Workspace helpers and agent-docs utilities for MetaObjects projects.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -56,7 +56,7 @@
56
56
  "access": "public"
57
57
  },
58
58
  "dependencies": {
59
- "@metaobjectsdev/metadata": "0.11.0-rc.1",
59
+ "@metaobjectsdev/metadata": "0.11.1-rc.1",
60
60
  "zod": "^3.23.0"
61
61
  },
62
62
  "devDependencies": {