diff --git a/AGENTS.md b/AGENTS.md index 5d0c29e98b..bde4ffec93 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -71,7 +71,7 @@ PyPI has had no product change since `0.25.0` — nothing is broken. - **Kotlin** — `codegen-kotlin` (KotlinPoet on JVM): entity + Exposed table + Spring controller + payload + relations + filter allowlist + validator + stored-proc + output-parser generators. `integration-tests-kotlin` runs the persistence-conformance corpus through Exposed against Testcontainers Postgres. **Cross-port conformance corpora** (every port runs the shared corpus): -- Metamodel: `fixtures/conformance/` (451 fixtures; 38 shared corpora in total — per-corpus counts + the corpus x port matrix live in `docs/CONFORMANCE.md`). TS / C# / Java / Python all green. +- Metamodel: `fixtures/conformance/` (454 fixtures; 38 shared corpora in total — per-corpus counts + the corpus x port matrix live in `docs/CONFORMANCE.md`). TS / C# / Java / Python all green. - Render: `fixtures/render-conformance/`. TS / C# / Java / Kotlin / Python byte-identical. - Persistence: `fixtures/persistence-conformance/`. **Query** scenarios run on every port (TS / C# / Java / Kotlin / Python), each provisioning its test DB by executing the committed, TS-produced `canonical/schema.postgres.sql` (Postgres only — Derby dropped for the cross-port query corpus, ADR-0015; the FR-044 `report-*` scenarios also run on SQLite, MySQL and D1 where a port has the engine, see [docs/CONFORMANCE.md](docs/CONFORMANCE.md)). The **migration** scenarios are exercised by **TS only** (TS owns schema migrations). **The corpus now gates WRITES, not just reads (SP-H):** an `op: roundtrip` scenario type INSERTs through each port's runtime/ORM write codec (NOT raw SQL), reads the row back, and asserts the wire-normalized value. The `AllTypes` entity (`roundtrip-all-types.yaml`) carries one field of **every** persistable `field.*` subtype — string/int/long/double/float/decimal/boolean/date/time/timestamp(+tz)/currency/enum/uuid/object — plus an **array-of-VO** `field.object @isArray @storage:jsonb` column (`labels`, written as 2-element / empty-`[]` / single-element arrays across the three rows) — so every subtype write+read (incl. the array-of-value-object jsonb codec) round-trips through every port against Testcontainers PG. (`field.byte`/`field.short`/`field.class` were cut as non-functional registration-only stubs — the matrix tracks only genuinely-supported subtypes; see `fixtures/registry-conformance/README.md` → "Per-subtype write-round-trip matrix".) - API-contract: `fixtures/api-contract-conformance/`. TS / C# / Java / Kotlin / Python all green — each port runs **two lanes**: a hand-rolled reference server AND its **generated** API artifact booted over HTTP (the deployed controller/routes; TS+C# full-stack vs Testcontainers PG, Java/Kotlin/Python generated controller + in-memory repo behind the consumer seam). The generated fan-out found 10 real deployment bugs golden snapshots missed. Three sub-corpora run the **generated lane only, on all five ports** — `write-through/`, `projection/` (F22: a view-only `object.projection` serves GET list + GET by id and answers every write verb with `405 {"error": "method_not_allowed"}`) and `report/` (FR-044: a view-backed `object.report` serves GET list, answers `POST` with that same `405`, and mounts no `/{id}` route). That is deliberate, not a gap: what is under test is whether a port's GENERATOR emits those routes, and a hand-rolled reference server would answer every scenario by construction. The `m2m/` sub-corpus also gates **TPH x M:N together** (base-declared, subtype-declared, abstract-mid-declared, a non-subtype source onto a subtype TARGET, and the cross-subtype source id answering `200 []`) — the two corpora were originally built disjoint (`tph/` had no relationships, `m2m/` no discriminators), which is precisely how that defect class survived. diff --git a/CHANGELOG.md b/CHANGELOG.md index 473b230f94..b40d03c06f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,13 +13,32 @@ here.** **`metamodelVersion` moves to `1.3`.** This release adds vocabulary (`field.duration`, `validator.exactlyOne`, `@constraintName`, `@condition`, `@maxLength` on `field.enum`, `@sequenceStart`, `@sequenceName`, `@flattenedColumnPrefix`, the `pascal` column rule, and -`@dbSetName`, a C#-only attr) and nothing that loaded before stops loading. A registry attr entry -gains `ports`, carried into the registry manifest: the ports that act on a language-specific attr -(`@dbSetName` names `["csharp"]`). A port that reports `1.2` does not know that vocabulary; upgrade -every port together. +`@dbSetName`, a C#-only attr) and nothing that loaded before stops loading. The registry gains two +fields on a type or attr entry, carried into the registry manifest: `implementedIn` (cross-port +vocabulary only the named ports implement so far, e.g. the `view.*` controls, `["typescript"]`) and +`ports` (vocabulary only the named ports ever act on, e.g. `@dbSetName`, `["csharp"]`, and +`@objectAdapter`, `["java", "kotlin"]`: the JVM runtime both share acts on it). The manifest's row +set grows by the `implementedIn` rows that used to be carved out. A port that reports `1.2` does not +know that vocabulary; upgrade every port together. ### Added +- **Cross-port vocabulary that only some ports implement so far (`implementedIn`).** A registry + type or attr may name the ports that implement it so far (`"implementedIn": ["typescript"]` on + its `spec/metamodel` entry, carried into the registry manifest). It is still cross-port + vocabulary: every port registers it and loads it strictly, and a port that has not implemented + it ignores it. The 13 generic `view.*` controls, `view.textarea @rows` and the five `view.image` + attrs are `["typescript"]`; `object.* @object` is `["java"]`. They used to be carved out of the + manifest (`PRESENTATION_ONLY`, `NATIVE_BINDING`); both carve-outs are gone, and the registry + canonical grows by those rows. `meta types` marks them `[ts; pending elsewhere]` / `[java; + pending elsewhere]` (it used to say `[ts-only]`, "the cross-port contract does not carry it"; its + JSON change is under Changed), and the metamodel docs now cover the view controls. + `@objectAdapter` joins `@dbSetName` as port-scoped (`"ports": ["java", "kotlin"]`). C#, Java, + Kotlin and Python now register the `metaobjects-ui-web` attrs (`view.textarea @rows` and the + `view.image` attrs), and C# and Python register `@object` / `@objectAdapter`, so a model that + uses any of them loads strictly in every port. Gated by the conformance fixtures + `view-kind1-controls`, `object-kind1-jvm-binding-attrs` and + `error-kind1-view-unregistered-attr`, and by the registry canonical. - **Port-scoped vocabulary, and `@dbSetName`.** A registry attr may name the ports that act on it (`"ports": ["csharp"]` on its `spec/metamodel` entry, carried into the registry manifest). Every port registers and type-checks it, so a model that carries it loads under every @@ -510,6 +529,12 @@ every port together. Python, `Verify` in C#, the `verify` field of `RenderRequest` in Java and Kotlin). If a template already named a missing variable, regenerate and fix the name; the generated helper text changes (TypeScript `prompts.ts` and Python helpers gain a `verify` argument). +- **Deprecated, CLI: `tsOnly` in `meta types --format json`; read `implementedIn`.** Each row + and attr now names the ports that implement it so far (`"implementedIn": ["typescript"]`), and a + port-scoped attr carries `ports`. `tsOnly` is still emitted through 1.3.x, derived from + `implementedIn` (`true` exactly when it is `["typescript"]`), and is removed in 1.4. The text + output's `[ts-only]` marker is now `[ts; pending elsewhere]`, and a port-scoped attr shows + `[-only]` (`[java+kotlin]` for `@objectAdapter`, which names two). - **C#, upgrade note: the next EF migration scaffolds your indexes and comments.** The generated context now declares every `@unique`, `identity.secondary` and `index.lookup` as an EF index diff --git a/agent-context/templates/always-on.md.mustache b/agent-context/templates/always-on.md.mustache index 73d371ac6c..9eef331f35 100644 --- a/agent-context/templates/always-on.md.mustache +++ b/agent-context/templates/always-on.md.mustache @@ -72,7 +72,7 @@ from. - **JVM:** serialize a MetaObject-backed instance (a `pojoAware`-flavor generated class, a runtime `ValueObject`, or any `MetaObjectAware` type) through the MetaObjects JSON layer — never hand-configure a Jackson/Gson mapper around the framework fields to make a default mapper cope. ## Authoring rules you must not violate -- **Search the vocabulary before concluding it cannot be expressed — `meta types `.** An unregistered TYPE or SUBTYPE fails the load in every command. An undeclared `@attr` is different: it fails `meta verify`, which loads strict, and NOT `meta gen`, which does not — so an invented attribute passes codegen silently and is caught by the drift gate rather than by the build. Either way inventing vocabulary is a failure you will hit, not a shortcut. Search names with `meta types `, names and descriptions with `--all` ("find it by what it does"), and one construct's valid `@attrs` with `meta types . --detail`; `--format json` returns the same answer as one machine-readable document, each attr with its `allowedValues`. Rows marked `[ts-only]` are TypeScript-only vocabulary the cross-port contract does not carry. `[-only]` (such as `[csharp-only]`) marks vocabulary only that port ever acts on. It is the Node `meta` CLI and, like `meta migrate`, works whatever your backend — it reads the registry, so it needs no project. Ask for NEW vocabulary only once that search comes up empty. +- **Search the vocabulary before concluding it cannot be expressed — `meta types `.** An unregistered TYPE or SUBTYPE fails the load in every command. An undeclared `@attr` is different: it fails `meta verify`, which loads strict, and NOT `meta gen`, which does not — so an invented attribute passes codegen silently and is caught by the drift gate rather than by the build. Either way inventing vocabulary is a failure you will hit, not a shortcut. Search names with `meta types `, names and descriptions with `--all` ("find it by what it does"), and one construct's valid `@attrs` with `meta types . --detail`; `--format json` returns the same answer as one machine-readable document, each attr with its `allowedValues`. Rows marked `[ts; pending elsewhere]` (or `[java; …]`) are cross-port vocabulary only that port implements so far: every port loads it, the others ignore it. `[-only]` (`[csharp-only]`; several ports: `[java+kotlin]`) marks vocabulary only those ports ever act on. It is the Node `meta` CLI and, like `meta migrate`, works whatever your backend — it reads the registry, so it needs no project. Ask for NEW vocabulary only once that search comes up empty. - Nodes are fused-key maps: `{".": { ... }}` (e.g. `{"field.string": {"name": "email"}}`) — never split the type and subtype into separate keys. - Attribute names are unique within a node; for multi-value use one array attr (`@values: [...]`). - An inline `@maxLength: 50` equals an `attr` child of the same name — never write both. diff --git a/docs/CONFORMANCE.md b/docs/CONFORMANCE.md index 9b4817e5ef..84f5b60641 100644 --- a/docs/CONFORMANCE.md +++ b/docs/CONFORMANCE.md @@ -26,7 +26,7 @@ regenerate with `ls -d fixtures//*/ | wc -l` for directory-shaped corpor | Corpus | Fixtures | TS | Java | Kotlin | C# | Python | |---|---|---|---|---|---|---| -| [`fixtures/conformance/`](../fixtures/conformance/) (metamodel) | 451 | ✓ | ✓ | inherits via `metadata-ktx` | ✓ | ✓ | +| [`fixtures/conformance/`](../fixtures/conformance/) (metamodel) | 454 | ✓ | ✓ | inherits via `metadata-ktx` | ✓ | ✓ | | [`fixtures/yaml-conformance/`](../fixtures/yaml-conformance/) | 16 | 16 / 16 | 15 / 16 (1 ledgered: `yaml-quoted-leading-zero` — Java pipeline strips quotes off `"007"`) | inherits via Java | 15 / 16 (1 ledgered: `error-yaml-coerced-hex-in-string` — YamlDotNet doesn't coerce `0xFF`) | 16 / 16 | | [`fixtures/verify-conformance/`](../fixtures/verify-conformance/) | 45 | ✓ | ✓ | inherits via Java | ✓ | ✓ | | [`fixtures/verify-strict-conformance/`](../fixtures/verify-strict-conformance/) | 1 | ✓ | — | — | — | ✓ | @@ -132,6 +132,30 @@ are tracked in [#544](https://github.com/metaobjectsdev/metaobjects/issues/544). - *TODO, Python:* the vocabulary loads; the runtime has no DDL path. If it gains one, the same semantic and pin apply. +**Cross-port vocabulary implemented in some ports so far (`implementedIn`).** Each entry +below is in the shared registry and the registry manifest, marked `implementedIn`. A port that +has not implemented it must still register it and load it strictly (and then ignore it); an +unregistered attr on it still fails. Gated by the conformance fixtures `view-kind1-controls`, +`object-kind1-jvm-binding-attrs` and `error-kind1-view-unregistered-attr`, and by the registry +canonical (`fixtures/registry-conformance/expected-registry.json`). + +- *Implemented in TypeScript only* (`implementedIn: ["typescript"]`). The TS web client and TS + form codegen act on them; no other port does yet. + - `view.checkbox`, `view.date`, `view.dropdown`, `view.hidden`, `view.hotlink`, `view.month`, + `view.number`, `view.password`, `view.radio`, `view.text`, `view.web` (types, no attrs) + - `view.textarea`, and its `@rows` + - `view.image`, and its `@accept`, `@aspectRatio`, `@maxBytes`, `@maxEdge`, `@store` +- *Implemented in Java only* (`implementedIn: ["java"]`): `object.* @object` (ADR-0001), the + native class an object binds to. Java's runtime acts on it; Java's own behaviour is unchanged. +- *Loads strictly in every port.* Each port registers the `metaobjects-ui-web` provider + (`view.textarea @rows`, the `view.image` attrs) and `@object` / `@objectAdapter` on + `object.*`, loads all three fixtures strictly, and emits `implementedIn` in its manifest, which + byte-matches the canonical in all five ports (`KindOneVocabularyTests` in C#; + `registry-conformance.test.ts` in TypeScript; `RegistryManifestConformanceTest` in Java and + Kotlin; `test_registry_conformance.py` in Python). +- *Port-scoped, for comparison* (`ports`, language-specific by nature, never "pending"): + `@dbSetName` (`["csharp"]`) and `@objectAdapter` (`["java", "kotlin"]`). + **Native index vocabulary and `@description` in the ORM models.** `meta migrate` creates every index (`identity.secondary`, `index.lookup`, a field's `@unique`, with `@where`, `@using`, `@orders`, `@expr` and the resolved name) and writes `@description` as `COMMENT ON`. What each @@ -326,7 +350,7 @@ unit-test runners (`bun test`, `dotnet test`, `pytest`, `mvn test`) pull Docker. ## Fixture-to-doc mapping -### `fixtures/conformance/` — metamodel loader + canonical serializer (451) +### `fixtures/conformance/` — metamodel loader + canonical serializer (454) | Fixture prefix | Feature doc | |---|---| @@ -687,7 +711,7 @@ JSON and verify payload feeds it unchanged. ## Orphaned fixtures (tested but not yet documented) -The fixtures in the nine corpora mapped above (metamodel 451 + yaml 16 + verify 45 +The fixtures in the nine corpora mapped above (metamodel 454 + yaml 16 + verify 45 + render 18 + persistence 62 + api-contract 123 + source-resolution 25 + scope 10 + dependency 47) each map to a feature doc, and so do the two requirement corpora, `shared-model-conformance`, the `cube-model` corpus and `explorer-conformance`, whose case lists live in their own READMEs. None are orphaned today. The remaining diff --git a/docs/features/image-upload.md b/docs/features/image-upload.md index 9d33ead5e0..14a32fd3e5 100644 --- a/docs/features/image-upload.md +++ b/docs/features/image-upload.md @@ -9,12 +9,12 @@ generated Zod schema, and the REST payload all carry a plain string. This is a **TS-web-only** feature — the upload widget, crop UI and adapter contract exist only in the TypeScript web client, and no other port ships one. -The `view.image` subtype itself LOADS in every port (all the generic `view.*` -controls register for loading everywhere; they stay manifest-excluded as -PRESENTATION_ONLY — `fixtures/registry-conformance/README.md`), but its five -attrs (`@aspectRatio` … `@maxBytes`) are registered only by the TypeScript -`metaobjects-ui-web` provider, so a `view.image` carrying them is authorable in -TypeScript alone. A backend port reads the field as the plain string it is. +`view.image` and its five attrs (`@aspectRatio` … `@maxBytes`) are cross-port +vocabulary that only TypeScript implements so far +(`implementedIn: ["typescript"]` in the registry manifest — +`fixtures/registry-conformance/README.md`). Every port registers the attrs and +loads them strictly, and none but TypeScript acts on them. A backend port reads +the field as the plain string it is. ## Authoring: `field.string` + `view.image` diff --git a/docs/features/migrations/base-subtypes-are-not-authorable.md b/docs/features/migrations/base-subtypes-are-not-authorable.md index 840c535766..288f42d3a6 100644 --- a/docs/features/migrations/base-subtypes-are-not-authorable.md +++ b/docs/features/migrations/base-subtypes-are-not-authorable.md @@ -71,9 +71,8 @@ the owning field's subtype, so a boolean default stays a boolean rather than bei concrete view subtypes while the non-TS ports registered only `view.base` and `view.currency` — so a backend port rejected `view.text` with `ERR_UNKNOWN_SUBTYPE`. That asymmetry is since gone: every port now registers the generic `view.*` controls (`view.text`, `view.textarea`, `view.checkbox`, -`view.radio`, `view.image`, …) for LOADING, still excluded from the cross-port manifest as -PRESENTATION_ONLY (`fixtures/registry-conformance/README.md`), while the attrs ON those controls -remain registered only by the TypeScript UI provider. The removal stands unchanged: `view.base` +`view.radio`, `view.image`, …), which are cross-port vocabulary only TypeScript implements so far +(`fixtures/registry-conformance/README.md`). The removal stands unchanged: `view.base` itself is refused in every port. Nothing is lost that carried information — a `view.base` node declared no kind and no attrs, and diff --git a/examples/showcase/site-payload.json b/examples/showcase/site-payload.json index 8124e84e1b..40de19a0d8 100644 --- a/examples/showcase/site-payload.json +++ b/examples/showcase/site-payload.json @@ -7,7 +7,7 @@ "metamodel": "1.3" }, "counts": { - "fixtures": 451, + "fixtures": 454, "corpora": 38, "baseTypes": 17 }, diff --git a/fixtures/agent-context-conformance/java-kotlin-react-tanstack/expected/.metaobjects/AGENTS.md b/fixtures/agent-context-conformance/java-kotlin-react-tanstack/expected/.metaobjects/AGENTS.md index 0e7f2570c9..48c0a14f43 100644 --- a/fixtures/agent-context-conformance/java-kotlin-react-tanstack/expected/.metaobjects/AGENTS.md +++ b/fixtures/agent-context-conformance/java-kotlin-react-tanstack/expected/.metaobjects/AGENTS.md @@ -50,7 +50,7 @@ Not there? List the missing generator — and a `docs` target, if `targets` has - **JVM:** serialize a MetaObject-backed instance (a `pojoAware`-flavor generated class, a runtime `ValueObject`, or any `MetaObjectAware` type) through the MetaObjects JSON layer — never hand-configure a Jackson/Gson mapper around the framework fields to make a default mapper cope. ## Authoring rules you must not violate -- **Search the vocabulary before concluding it cannot be expressed — `meta types `.** An unregistered TYPE or SUBTYPE fails the load in every command. An undeclared `@attr` is different: it fails `meta verify`, which loads strict, and NOT `meta gen`, which does not — so an invented attribute passes codegen silently and is caught by the drift gate rather than by the build. Either way inventing vocabulary is a failure you will hit, not a shortcut. Search names with `meta types `, names and descriptions with `--all` ("find it by what it does"), and one construct's valid `@attrs` with `meta types . --detail`; `--format json` returns the same answer as one machine-readable document, each attr with its `allowedValues`. Rows marked `[ts-only]` are TypeScript-only vocabulary the cross-port contract does not carry. `[-only]` (such as `[csharp-only]`) marks vocabulary only that port ever acts on. It is the Node `meta` CLI and, like `meta migrate`, works whatever your backend — it reads the registry, so it needs no project. Ask for NEW vocabulary only once that search comes up empty. +- **Search the vocabulary before concluding it cannot be expressed — `meta types `.** An unregistered TYPE or SUBTYPE fails the load in every command. An undeclared `@attr` is different: it fails `meta verify`, which loads strict, and NOT `meta gen`, which does not — so an invented attribute passes codegen silently and is caught by the drift gate rather than by the build. Either way inventing vocabulary is a failure you will hit, not a shortcut. Search names with `meta types `, names and descriptions with `--all` ("find it by what it does"), and one construct's valid `@attrs` with `meta types . --detail`; `--format json` returns the same answer as one machine-readable document, each attr with its `allowedValues`. Rows marked `[ts; pending elsewhere]` (or `[java; …]`) are cross-port vocabulary only that port implements so far: every port loads it, the others ignore it. `[-only]` (`[csharp-only]`; several ports: `[java+kotlin]`) marks vocabulary only those ports ever act on. It is the Node `meta` CLI and, like `meta migrate`, works whatever your backend — it reads the registry, so it needs no project. Ask for NEW vocabulary only once that search comes up empty. - Nodes are fused-key maps: `{".": { ... }}` (e.g. `{"field.string": {"name": "email"}}`) — never split the type and subtype into separate keys. - Attribute names are unique within a node; for multi-value use one array attr (`@values: [...]`). - An inline `@maxLength: 50` equals an `attr` child of the same name — never write both. diff --git a/fixtures/agent-context-conformance/java-kotlin-react-tanstack/expected/.metaobjects/CLAUDE.md b/fixtures/agent-context-conformance/java-kotlin-react-tanstack/expected/.metaobjects/CLAUDE.md index 0e7f2570c9..48c0a14f43 100644 --- a/fixtures/agent-context-conformance/java-kotlin-react-tanstack/expected/.metaobjects/CLAUDE.md +++ b/fixtures/agent-context-conformance/java-kotlin-react-tanstack/expected/.metaobjects/CLAUDE.md @@ -50,7 +50,7 @@ Not there? List the missing generator — and a `docs` target, if `targets` has - **JVM:** serialize a MetaObject-backed instance (a `pojoAware`-flavor generated class, a runtime `ValueObject`, or any `MetaObjectAware` type) through the MetaObjects JSON layer — never hand-configure a Jackson/Gson mapper around the framework fields to make a default mapper cope. ## Authoring rules you must not violate -- **Search the vocabulary before concluding it cannot be expressed — `meta types `.** An unregistered TYPE or SUBTYPE fails the load in every command. An undeclared `@attr` is different: it fails `meta verify`, which loads strict, and NOT `meta gen`, which does not — so an invented attribute passes codegen silently and is caught by the drift gate rather than by the build. Either way inventing vocabulary is a failure you will hit, not a shortcut. Search names with `meta types `, names and descriptions with `--all` ("find it by what it does"), and one construct's valid `@attrs` with `meta types . --detail`; `--format json` returns the same answer as one machine-readable document, each attr with its `allowedValues`. Rows marked `[ts-only]` are TypeScript-only vocabulary the cross-port contract does not carry. `[-only]` (such as `[csharp-only]`) marks vocabulary only that port ever acts on. It is the Node `meta` CLI and, like `meta migrate`, works whatever your backend — it reads the registry, so it needs no project. Ask for NEW vocabulary only once that search comes up empty. +- **Search the vocabulary before concluding it cannot be expressed — `meta types `.** An unregistered TYPE or SUBTYPE fails the load in every command. An undeclared `@attr` is different: it fails `meta verify`, which loads strict, and NOT `meta gen`, which does not — so an invented attribute passes codegen silently and is caught by the drift gate rather than by the build. Either way inventing vocabulary is a failure you will hit, not a shortcut. Search names with `meta types `, names and descriptions with `--all` ("find it by what it does"), and one construct's valid `@attrs` with `meta types . --detail`; `--format json` returns the same answer as one machine-readable document, each attr with its `allowedValues`. Rows marked `[ts; pending elsewhere]` (or `[java; …]`) are cross-port vocabulary only that port implements so far: every port loads it, the others ignore it. `[-only]` (`[csharp-only]`; several ports: `[java+kotlin]`) marks vocabulary only those ports ever act on. It is the Node `meta` CLI and, like `meta migrate`, works whatever your backend — it reads the registry, so it needs no project. Ask for NEW vocabulary only once that search comes up empty. - Nodes are fused-key maps: `{".": { ... }}` (e.g. `{"field.string": {"name": "email"}}`) — never split the type and subtype into separate keys. - Attribute names are unique within a node; for multi-value use one array attr (`@values: [...]`). - An inline `@maxLength: 50` equals an `attr` child of the same name — never write both. diff --git a/fixtures/agent-context-conformance/java-react/expected/.metaobjects/AGENTS.md b/fixtures/agent-context-conformance/java-react/expected/.metaobjects/AGENTS.md index 484509de51..44eb9f1644 100644 --- a/fixtures/agent-context-conformance/java-react/expected/.metaobjects/AGENTS.md +++ b/fixtures/agent-context-conformance/java-react/expected/.metaobjects/AGENTS.md @@ -50,7 +50,7 @@ Not there? List the missing generator — and a `docs` target, if `targets` has - **JVM:** serialize a MetaObject-backed instance (a `pojoAware`-flavor generated class, a runtime `ValueObject`, or any `MetaObjectAware` type) through the MetaObjects JSON layer — never hand-configure a Jackson/Gson mapper around the framework fields to make a default mapper cope. ## Authoring rules you must not violate -- **Search the vocabulary before concluding it cannot be expressed — `meta types `.** An unregistered TYPE or SUBTYPE fails the load in every command. An undeclared `@attr` is different: it fails `meta verify`, which loads strict, and NOT `meta gen`, which does not — so an invented attribute passes codegen silently and is caught by the drift gate rather than by the build. Either way inventing vocabulary is a failure you will hit, not a shortcut. Search names with `meta types `, names and descriptions with `--all` ("find it by what it does"), and one construct's valid `@attrs` with `meta types . --detail`; `--format json` returns the same answer as one machine-readable document, each attr with its `allowedValues`. Rows marked `[ts-only]` are TypeScript-only vocabulary the cross-port contract does not carry. `[-only]` (such as `[csharp-only]`) marks vocabulary only that port ever acts on. It is the Node `meta` CLI and, like `meta migrate`, works whatever your backend — it reads the registry, so it needs no project. Ask for NEW vocabulary only once that search comes up empty. +- **Search the vocabulary before concluding it cannot be expressed — `meta types `.** An unregistered TYPE or SUBTYPE fails the load in every command. An undeclared `@attr` is different: it fails `meta verify`, which loads strict, and NOT `meta gen`, which does not — so an invented attribute passes codegen silently and is caught by the drift gate rather than by the build. Either way inventing vocabulary is a failure you will hit, not a shortcut. Search names with `meta types `, names and descriptions with `--all` ("find it by what it does"), and one construct's valid `@attrs` with `meta types . --detail`; `--format json` returns the same answer as one machine-readable document, each attr with its `allowedValues`. Rows marked `[ts; pending elsewhere]` (or `[java; …]`) are cross-port vocabulary only that port implements so far: every port loads it, the others ignore it. `[-only]` (`[csharp-only]`; several ports: `[java+kotlin]`) marks vocabulary only those ports ever act on. It is the Node `meta` CLI and, like `meta migrate`, works whatever your backend — it reads the registry, so it needs no project. Ask for NEW vocabulary only once that search comes up empty. - Nodes are fused-key maps: `{".": { ... }}` (e.g. `{"field.string": {"name": "email"}}`) — never split the type and subtype into separate keys. - Attribute names are unique within a node; for multi-value use one array attr (`@values: [...]`). - An inline `@maxLength: 50` equals an `attr` child of the same name — never write both. diff --git a/fixtures/agent-context-conformance/java-react/expected/.metaobjects/CLAUDE.md b/fixtures/agent-context-conformance/java-react/expected/.metaobjects/CLAUDE.md index 484509de51..44eb9f1644 100644 --- a/fixtures/agent-context-conformance/java-react/expected/.metaobjects/CLAUDE.md +++ b/fixtures/agent-context-conformance/java-react/expected/.metaobjects/CLAUDE.md @@ -50,7 +50,7 @@ Not there? List the missing generator — and a `docs` target, if `targets` has - **JVM:** serialize a MetaObject-backed instance (a `pojoAware`-flavor generated class, a runtime `ValueObject`, or any `MetaObjectAware` type) through the MetaObjects JSON layer — never hand-configure a Jackson/Gson mapper around the framework fields to make a default mapper cope. ## Authoring rules you must not violate -- **Search the vocabulary before concluding it cannot be expressed — `meta types `.** An unregistered TYPE or SUBTYPE fails the load in every command. An undeclared `@attr` is different: it fails `meta verify`, which loads strict, and NOT `meta gen`, which does not — so an invented attribute passes codegen silently and is caught by the drift gate rather than by the build. Either way inventing vocabulary is a failure you will hit, not a shortcut. Search names with `meta types `, names and descriptions with `--all` ("find it by what it does"), and one construct's valid `@attrs` with `meta types . --detail`; `--format json` returns the same answer as one machine-readable document, each attr with its `allowedValues`. Rows marked `[ts-only]` are TypeScript-only vocabulary the cross-port contract does not carry. `[-only]` (such as `[csharp-only]`) marks vocabulary only that port ever acts on. It is the Node `meta` CLI and, like `meta migrate`, works whatever your backend — it reads the registry, so it needs no project. Ask for NEW vocabulary only once that search comes up empty. +- **Search the vocabulary before concluding it cannot be expressed — `meta types `.** An unregistered TYPE or SUBTYPE fails the load in every command. An undeclared `@attr` is different: it fails `meta verify`, which loads strict, and NOT `meta gen`, which does not — so an invented attribute passes codegen silently and is caught by the drift gate rather than by the build. Either way inventing vocabulary is a failure you will hit, not a shortcut. Search names with `meta types `, names and descriptions with `--all` ("find it by what it does"), and one construct's valid `@attrs` with `meta types . --detail`; `--format json` returns the same answer as one machine-readable document, each attr with its `allowedValues`. Rows marked `[ts; pending elsewhere]` (or `[java; …]`) are cross-port vocabulary only that port implements so far: every port loads it, the others ignore it. `[-only]` (`[csharp-only]`; several ports: `[java+kotlin]`) marks vocabulary only those ports ever act on. It is the Node `meta` CLI and, like `meta migrate`, works whatever your backend — it reads the registry, so it needs no project. Ask for NEW vocabulary only once that search comes up empty. - Nodes are fused-key maps: `{".": { ... }}` (e.g. `{"field.string": {"name": "email"}}`) — never split the type and subtype into separate keys. - Attribute names are unique within a node; for multi-value use one array attr (`@values: [...]`). - An inline `@maxLength: 50` equals an `attr` child of the same name — never write both. diff --git a/fixtures/agent-context-conformance/python/expected/.metaobjects/AGENTS.md b/fixtures/agent-context-conformance/python/expected/.metaobjects/AGENTS.md index 7bd3174d19..ece01bdac0 100644 --- a/fixtures/agent-context-conformance/python/expected/.metaobjects/AGENTS.md +++ b/fixtures/agent-context-conformance/python/expected/.metaobjects/AGENTS.md @@ -47,7 +47,7 @@ from. - **JVM:** serialize a MetaObject-backed instance (a `pojoAware`-flavor generated class, a runtime `ValueObject`, or any `MetaObjectAware` type) through the MetaObjects JSON layer — never hand-configure a Jackson/Gson mapper around the framework fields to make a default mapper cope. ## Authoring rules you must not violate -- **Search the vocabulary before concluding it cannot be expressed — `meta types `.** An unregistered TYPE or SUBTYPE fails the load in every command. An undeclared `@attr` is different: it fails `meta verify`, which loads strict, and NOT `meta gen`, which does not — so an invented attribute passes codegen silently and is caught by the drift gate rather than by the build. Either way inventing vocabulary is a failure you will hit, not a shortcut. Search names with `meta types `, names and descriptions with `--all` ("find it by what it does"), and one construct's valid `@attrs` with `meta types . --detail`; `--format json` returns the same answer as one machine-readable document, each attr with its `allowedValues`. Rows marked `[ts-only]` are TypeScript-only vocabulary the cross-port contract does not carry. `[-only]` (such as `[csharp-only]`) marks vocabulary only that port ever acts on. It is the Node `meta` CLI and, like `meta migrate`, works whatever your backend — it reads the registry, so it needs no project. Ask for NEW vocabulary only once that search comes up empty. +- **Search the vocabulary before concluding it cannot be expressed — `meta types `.** An unregistered TYPE or SUBTYPE fails the load in every command. An undeclared `@attr` is different: it fails `meta verify`, which loads strict, and NOT `meta gen`, which does not — so an invented attribute passes codegen silently and is caught by the drift gate rather than by the build. Either way inventing vocabulary is a failure you will hit, not a shortcut. Search names with `meta types `, names and descriptions with `--all` ("find it by what it does"), and one construct's valid `@attrs` with `meta types . --detail`; `--format json` returns the same answer as one machine-readable document, each attr with its `allowedValues`. Rows marked `[ts; pending elsewhere]` (or `[java; …]`) are cross-port vocabulary only that port implements so far: every port loads it, the others ignore it. `[-only]` (`[csharp-only]`; several ports: `[java+kotlin]`) marks vocabulary only those ports ever act on. It is the Node `meta` CLI and, like `meta migrate`, works whatever your backend — it reads the registry, so it needs no project. Ask for NEW vocabulary only once that search comes up empty. - Nodes are fused-key maps: `{".": { ... }}` (e.g. `{"field.string": {"name": "email"}}`) — never split the type and subtype into separate keys. - Attribute names are unique within a node; for multi-value use one array attr (`@values: [...]`). - An inline `@maxLength: 50` equals an `attr` child of the same name — never write both. diff --git a/fixtures/agent-context-conformance/python/expected/.metaobjects/CLAUDE.md b/fixtures/agent-context-conformance/python/expected/.metaobjects/CLAUDE.md index 7bd3174d19..ece01bdac0 100644 --- a/fixtures/agent-context-conformance/python/expected/.metaobjects/CLAUDE.md +++ b/fixtures/agent-context-conformance/python/expected/.metaobjects/CLAUDE.md @@ -47,7 +47,7 @@ from. - **JVM:** serialize a MetaObject-backed instance (a `pojoAware`-flavor generated class, a runtime `ValueObject`, or any `MetaObjectAware` type) through the MetaObjects JSON layer — never hand-configure a Jackson/Gson mapper around the framework fields to make a default mapper cope. ## Authoring rules you must not violate -- **Search the vocabulary before concluding it cannot be expressed — `meta types `.** An unregistered TYPE or SUBTYPE fails the load in every command. An undeclared `@attr` is different: it fails `meta verify`, which loads strict, and NOT `meta gen`, which does not — so an invented attribute passes codegen silently and is caught by the drift gate rather than by the build. Either way inventing vocabulary is a failure you will hit, not a shortcut. Search names with `meta types `, names and descriptions with `--all` ("find it by what it does"), and one construct's valid `@attrs` with `meta types . --detail`; `--format json` returns the same answer as one machine-readable document, each attr with its `allowedValues`. Rows marked `[ts-only]` are TypeScript-only vocabulary the cross-port contract does not carry. `[-only]` (such as `[csharp-only]`) marks vocabulary only that port ever acts on. It is the Node `meta` CLI and, like `meta migrate`, works whatever your backend — it reads the registry, so it needs no project. Ask for NEW vocabulary only once that search comes up empty. +- **Search the vocabulary before concluding it cannot be expressed — `meta types `.** An unregistered TYPE or SUBTYPE fails the load in every command. An undeclared `@attr` is different: it fails `meta verify`, which loads strict, and NOT `meta gen`, which does not — so an invented attribute passes codegen silently and is caught by the drift gate rather than by the build. Either way inventing vocabulary is a failure you will hit, not a shortcut. Search names with `meta types `, names and descriptions with `--all` ("find it by what it does"), and one construct's valid `@attrs` with `meta types . --detail`; `--format json` returns the same answer as one machine-readable document, each attr with its `allowedValues`. Rows marked `[ts; pending elsewhere]` (or `[java; …]`) are cross-port vocabulary only that port implements so far: every port loads it, the others ignore it. `[-only]` (`[csharp-only]`; several ports: `[java+kotlin]`) marks vocabulary only those ports ever act on. It is the Node `meta` CLI and, like `meta migrate`, works whatever your backend — it reads the registry, so it needs no project. Ask for NEW vocabulary only once that search comes up empty. - Nodes are fused-key maps: `{".": { ... }}` (e.g. `{"field.string": {"name": "email"}}`) — never split the type and subtype into separate keys. - Attribute names are unique within a node; for multi-value use one array attr (`@values: [...]`). - An inline `@maxLength: 50` equals an `attr` child of the same name — never write both. diff --git a/fixtures/agent-context-conformance/ts-react-tanstack/expected/.metaobjects/AGENTS.md b/fixtures/agent-context-conformance/ts-react-tanstack/expected/.metaobjects/AGENTS.md index ba41481275..2b67e4ec0b 100644 --- a/fixtures/agent-context-conformance/ts-react-tanstack/expected/.metaobjects/AGENTS.md +++ b/fixtures/agent-context-conformance/ts-react-tanstack/expected/.metaobjects/AGENTS.md @@ -50,7 +50,7 @@ Not there? List the missing generator — and a `docs` target, if `targets` has - **JVM:** serialize a MetaObject-backed instance (a `pojoAware`-flavor generated class, a runtime `ValueObject`, or any `MetaObjectAware` type) through the MetaObjects JSON layer — never hand-configure a Jackson/Gson mapper around the framework fields to make a default mapper cope. ## Authoring rules you must not violate -- **Search the vocabulary before concluding it cannot be expressed — `meta types `.** An unregistered TYPE or SUBTYPE fails the load in every command. An undeclared `@attr` is different: it fails `meta verify`, which loads strict, and NOT `meta gen`, which does not — so an invented attribute passes codegen silently and is caught by the drift gate rather than by the build. Either way inventing vocabulary is a failure you will hit, not a shortcut. Search names with `meta types `, names and descriptions with `--all` ("find it by what it does"), and one construct's valid `@attrs` with `meta types . --detail`; `--format json` returns the same answer as one machine-readable document, each attr with its `allowedValues`. Rows marked `[ts-only]` are TypeScript-only vocabulary the cross-port contract does not carry. `[-only]` (such as `[csharp-only]`) marks vocabulary only that port ever acts on. It is the Node `meta` CLI and, like `meta migrate`, works whatever your backend — it reads the registry, so it needs no project. Ask for NEW vocabulary only once that search comes up empty. +- **Search the vocabulary before concluding it cannot be expressed — `meta types `.** An unregistered TYPE or SUBTYPE fails the load in every command. An undeclared `@attr` is different: it fails `meta verify`, which loads strict, and NOT `meta gen`, which does not — so an invented attribute passes codegen silently and is caught by the drift gate rather than by the build. Either way inventing vocabulary is a failure you will hit, not a shortcut. Search names with `meta types `, names and descriptions with `--all` ("find it by what it does"), and one construct's valid `@attrs` with `meta types . --detail`; `--format json` returns the same answer as one machine-readable document, each attr with its `allowedValues`. Rows marked `[ts; pending elsewhere]` (or `[java; …]`) are cross-port vocabulary only that port implements so far: every port loads it, the others ignore it. `[-only]` (`[csharp-only]`; several ports: `[java+kotlin]`) marks vocabulary only those ports ever act on. It is the Node `meta` CLI and, like `meta migrate`, works whatever your backend — it reads the registry, so it needs no project. Ask for NEW vocabulary only once that search comes up empty. - Nodes are fused-key maps: `{".": { ... }}` (e.g. `{"field.string": {"name": "email"}}`) — never split the type and subtype into separate keys. - Attribute names are unique within a node; for multi-value use one array attr (`@values: [...]`). - An inline `@maxLength: 50` equals an `attr` child of the same name — never write both. diff --git a/fixtures/agent-context-conformance/ts-react-tanstack/expected/.metaobjects/CLAUDE.md b/fixtures/agent-context-conformance/ts-react-tanstack/expected/.metaobjects/CLAUDE.md index ba41481275..2b67e4ec0b 100644 --- a/fixtures/agent-context-conformance/ts-react-tanstack/expected/.metaobjects/CLAUDE.md +++ b/fixtures/agent-context-conformance/ts-react-tanstack/expected/.metaobjects/CLAUDE.md @@ -50,7 +50,7 @@ Not there? List the missing generator — and a `docs` target, if `targets` has - **JVM:** serialize a MetaObject-backed instance (a `pojoAware`-flavor generated class, a runtime `ValueObject`, or any `MetaObjectAware` type) through the MetaObjects JSON layer — never hand-configure a Jackson/Gson mapper around the framework fields to make a default mapper cope. ## Authoring rules you must not violate -- **Search the vocabulary before concluding it cannot be expressed — `meta types `.** An unregistered TYPE or SUBTYPE fails the load in every command. An undeclared `@attr` is different: it fails `meta verify`, which loads strict, and NOT `meta gen`, which does not — so an invented attribute passes codegen silently and is caught by the drift gate rather than by the build. Either way inventing vocabulary is a failure you will hit, not a shortcut. Search names with `meta types `, names and descriptions with `--all` ("find it by what it does"), and one construct's valid `@attrs` with `meta types . --detail`; `--format json` returns the same answer as one machine-readable document, each attr with its `allowedValues`. Rows marked `[ts-only]` are TypeScript-only vocabulary the cross-port contract does not carry. `[-only]` (such as `[csharp-only]`) marks vocabulary only that port ever acts on. It is the Node `meta` CLI and, like `meta migrate`, works whatever your backend — it reads the registry, so it needs no project. Ask for NEW vocabulary only once that search comes up empty. +- **Search the vocabulary before concluding it cannot be expressed — `meta types `.** An unregistered TYPE or SUBTYPE fails the load in every command. An undeclared `@attr` is different: it fails `meta verify`, which loads strict, and NOT `meta gen`, which does not — so an invented attribute passes codegen silently and is caught by the drift gate rather than by the build. Either way inventing vocabulary is a failure you will hit, not a shortcut. Search names with `meta types `, names and descriptions with `--all` ("find it by what it does"), and one construct's valid `@attrs` with `meta types . --detail`; `--format json` returns the same answer as one machine-readable document, each attr with its `allowedValues`. Rows marked `[ts; pending elsewhere]` (or `[java; …]`) are cross-port vocabulary only that port implements so far: every port loads it, the others ignore it. `[-only]` (`[csharp-only]`; several ports: `[java+kotlin]`) marks vocabulary only those ports ever act on. It is the Node `meta` CLI and, like `meta migrate`, works whatever your backend — it reads the registry, so it needs no project. Ask for NEW vocabulary only once that search comes up empty. - Nodes are fused-key maps: `{".": { ... }}` (e.g. `{"field.string": {"name": "email"}}`) — never split the type and subtype into separate keys. - Attribute names are unique within a node; for multi-value use one array attr (`@values: [...]`). - An inline `@maxLength: 50` equals an `attr` child of the same name — never write both. diff --git a/fixtures/agent-context-conformance/ts-requirements/expected/.metaobjects/AGENTS.md b/fixtures/agent-context-conformance/ts-requirements/expected/.metaobjects/AGENTS.md index 72b81c75ed..2fbe964b28 100644 --- a/fixtures/agent-context-conformance/ts-requirements/expected/.metaobjects/AGENTS.md +++ b/fixtures/agent-context-conformance/ts-requirements/expected/.metaobjects/AGENTS.md @@ -50,7 +50,7 @@ Not there? List the missing generator — and a `docs` target, if `targets` has - **JVM:** serialize a MetaObject-backed instance (a `pojoAware`-flavor generated class, a runtime `ValueObject`, or any `MetaObjectAware` type) through the MetaObjects JSON layer — never hand-configure a Jackson/Gson mapper around the framework fields to make a default mapper cope. ## Authoring rules you must not violate -- **Search the vocabulary before concluding it cannot be expressed — `meta types `.** An unregistered TYPE or SUBTYPE fails the load in every command. An undeclared `@attr` is different: it fails `meta verify`, which loads strict, and NOT `meta gen`, which does not — so an invented attribute passes codegen silently and is caught by the drift gate rather than by the build. Either way inventing vocabulary is a failure you will hit, not a shortcut. Search names with `meta types `, names and descriptions with `--all` ("find it by what it does"), and one construct's valid `@attrs` with `meta types . --detail`; `--format json` returns the same answer as one machine-readable document, each attr with its `allowedValues`. Rows marked `[ts-only]` are TypeScript-only vocabulary the cross-port contract does not carry. `[-only]` (such as `[csharp-only]`) marks vocabulary only that port ever acts on. It is the Node `meta` CLI and, like `meta migrate`, works whatever your backend — it reads the registry, so it needs no project. Ask for NEW vocabulary only once that search comes up empty. +- **Search the vocabulary before concluding it cannot be expressed — `meta types `.** An unregistered TYPE or SUBTYPE fails the load in every command. An undeclared `@attr` is different: it fails `meta verify`, which loads strict, and NOT `meta gen`, which does not — so an invented attribute passes codegen silently and is caught by the drift gate rather than by the build. Either way inventing vocabulary is a failure you will hit, not a shortcut. Search names with `meta types `, names and descriptions with `--all` ("find it by what it does"), and one construct's valid `@attrs` with `meta types . --detail`; `--format json` returns the same answer as one machine-readable document, each attr with its `allowedValues`. Rows marked `[ts; pending elsewhere]` (or `[java; …]`) are cross-port vocabulary only that port implements so far: every port loads it, the others ignore it. `[-only]` (`[csharp-only]`; several ports: `[java+kotlin]`) marks vocabulary only those ports ever act on. It is the Node `meta` CLI and, like `meta migrate`, works whatever your backend — it reads the registry, so it needs no project. Ask for NEW vocabulary only once that search comes up empty. - Nodes are fused-key maps: `{".": { ... }}` (e.g. `{"field.string": {"name": "email"}}`) — never split the type and subtype into separate keys. - Attribute names are unique within a node; for multi-value use one array attr (`@values: [...]`). - An inline `@maxLength: 50` equals an `attr` child of the same name — never write both. diff --git a/fixtures/agent-context-conformance/ts-requirements/expected/.metaobjects/CLAUDE.md b/fixtures/agent-context-conformance/ts-requirements/expected/.metaobjects/CLAUDE.md index 72b81c75ed..2fbe964b28 100644 --- a/fixtures/agent-context-conformance/ts-requirements/expected/.metaobjects/CLAUDE.md +++ b/fixtures/agent-context-conformance/ts-requirements/expected/.metaobjects/CLAUDE.md @@ -50,7 +50,7 @@ Not there? List the missing generator — and a `docs` target, if `targets` has - **JVM:** serialize a MetaObject-backed instance (a `pojoAware`-flavor generated class, a runtime `ValueObject`, or any `MetaObjectAware` type) through the MetaObjects JSON layer — never hand-configure a Jackson/Gson mapper around the framework fields to make a default mapper cope. ## Authoring rules you must not violate -- **Search the vocabulary before concluding it cannot be expressed — `meta types `.** An unregistered TYPE or SUBTYPE fails the load in every command. An undeclared `@attr` is different: it fails `meta verify`, which loads strict, and NOT `meta gen`, which does not — so an invented attribute passes codegen silently and is caught by the drift gate rather than by the build. Either way inventing vocabulary is a failure you will hit, not a shortcut. Search names with `meta types `, names and descriptions with `--all` ("find it by what it does"), and one construct's valid `@attrs` with `meta types . --detail`; `--format json` returns the same answer as one machine-readable document, each attr with its `allowedValues`. Rows marked `[ts-only]` are TypeScript-only vocabulary the cross-port contract does not carry. `[-only]` (such as `[csharp-only]`) marks vocabulary only that port ever acts on. It is the Node `meta` CLI and, like `meta migrate`, works whatever your backend — it reads the registry, so it needs no project. Ask for NEW vocabulary only once that search comes up empty. +- **Search the vocabulary before concluding it cannot be expressed — `meta types `.** An unregistered TYPE or SUBTYPE fails the load in every command. An undeclared `@attr` is different: it fails `meta verify`, which loads strict, and NOT `meta gen`, which does not — so an invented attribute passes codegen silently and is caught by the drift gate rather than by the build. Either way inventing vocabulary is a failure you will hit, not a shortcut. Search names with `meta types `, names and descriptions with `--all` ("find it by what it does"), and one construct's valid `@attrs` with `meta types . --detail`; `--format json` returns the same answer as one machine-readable document, each attr with its `allowedValues`. Rows marked `[ts; pending elsewhere]` (or `[java; …]`) are cross-port vocabulary only that port implements so far: every port loads it, the others ignore it. `[-only]` (`[csharp-only]`; several ports: `[java+kotlin]`) marks vocabulary only those ports ever act on. It is the Node `meta` CLI and, like `meta migrate`, works whatever your backend — it reads the registry, so it needs no project. Ask for NEW vocabulary only once that search comes up empty. - Nodes are fused-key maps: `{".": { ... }}` (e.g. `{"field.string": {"name": "email"}}`) — never split the type and subtype into separate keys. - Attribute names are unique within a node; for multi-value use one array attr (`@values: [...]`). - An inline `@maxLength: 50` equals an `attr` child of the same name — never write both. diff --git a/fixtures/conformance/error-kind1-view-unregistered-attr/expected-errors.json b/fixtures/conformance/error-kind1-view-unregistered-attr/expected-errors.json new file mode 100644 index 0000000000..3a8893091b --- /dev/null +++ b/fixtures/conformance/error-kind1-view-unregistered-attr/expected-errors.json @@ -0,0 +1,15 @@ +{ + "errors": [ + { + "code": "ERR_UNKNOWN_ATTR", + "source": { + "format": "json", + "files": [ + "meta.catalog.json" + ], + "jsonPath": "$['metadata.root'].children[0]['object.entity'].children[1]['field.string'].children[0]['view.image']" + } + } + ], + "warnings": [] +} diff --git a/fixtures/conformance/error-kind1-view-unregistered-attr/input/meta.catalog.json b/fixtures/conformance/error-kind1-view-unregistered-attr/input/meta.catalog.json new file mode 100644 index 0000000000..3b4cf58f39 --- /dev/null +++ b/fixtures/conformance/error-kind1-view-unregistered-attr/input/meta.catalog.json @@ -0,0 +1,40 @@ +{ + "metadata.root": { + "package": "acme::catalog", + "children": [ + { + "object.entity": { + "name": "Product", + "children": [ + { + "field.long": { + "name": "id" + } + }, + { + "field.string": { + "name": "coverKey", + "children": [ + { + "view.image": { + "name": "form", + "@cropShape": "circle" + } + } + ] + } + }, + { + "identity.primary": { + "name": "pk", + "@fields": [ + "id" + ] + } + } + ] + } + } + ] + } +} diff --git a/fixtures/conformance/object-kind1-jvm-binding-attrs/expected.json b/fixtures/conformance/object-kind1-jvm-binding-attrs/expected.json new file mode 100644 index 0000000000..b22884d21e --- /dev/null +++ b/fixtures/conformance/object-kind1-jvm-binding-attrs/expected.json @@ -0,0 +1,110 @@ +{ + "metadata.root": { + "package": "acme::catalog", + "children": [ + { + "object.entity": { + "name": "Product", + "@object": "com.acme.catalog.Product", + "@objectAdapter": "com.acme.catalog.ProductAdapter", + "children": [ + { + "source.rdb": { + "@table": "products" + } + }, + { + "field.long": { + "name": "id" + } + }, + { + "field.string": { + "name": "sku" + } + }, + { + "identity.primary": { + "name": "pk", + "@fields": [ + "id" + ] + } + }, + { + "dimension.attribute": { + "name": "sku", + "@of": "acme::catalog::Product.sku" + } + }, + { + "measure.aggregate": { + "name": "products", + "@agg": "count", + "@of": [ + "acme::catalog::Product.id" + ] + } + } + ] + } + }, + { + "object.value": { + "name": "Price", + "@object": "com.acme.catalog.Price", + "@objectAdapter": "com.acme.catalog.PriceAdapter", + "children": [ + { + "field.string": { + "name": "currency" + } + } + ] + } + }, + { + "object.projection": { + "name": "ProductSummary", + "@object": "com.acme.catalog.ProductSummary", + "@objectAdapter": "com.acme.catalog.ProductSummaryAdapter", + "children": [ + { + "source.rdb": { + "@kind": "view", + "@view": "v_product_summary" + } + }, + { + "field.string": { + "name": "sku" + } + } + ] + } + }, + { + "object.report": { + "name": "ProductCounts", + "@dimensions": [ + "sku" + ], + "@from": "acme::catalog::Product", + "@measures": [ + "products" + ], + "@object": "com.acme.catalog.ProductCounts", + "@objectAdapter": "com.acme.catalog.ProductCountsAdapter", + "children": [ + { + "source.rdb": { + "@kind": "view", + "@view": "v_product_counts" + } + } + ] + } + } + ] + } +} diff --git a/fixtures/conformance/object-kind1-jvm-binding-attrs/input/meta.catalog.json b/fixtures/conformance/object-kind1-jvm-binding-attrs/input/meta.catalog.json new file mode 100644 index 0000000000..150783e49b --- /dev/null +++ b/fixtures/conformance/object-kind1-jvm-binding-attrs/input/meta.catalog.json @@ -0,0 +1,108 @@ +{ + "metadata.root": { + "package": "acme::catalog", + "children": [ + { + "object.entity": { + "name": "Product", + "@object": "com.acme.catalog.Product", + "@objectAdapter": "com.acme.catalog.ProductAdapter", + "children": [ + { + "source.rdb": { + "@table": "products" + } + }, + { + "field.long": { + "name": "id" + } + }, + { + "field.string": { + "name": "sku" + } + }, + { + "identity.primary": { + "name": "pk", + "@fields": [ + "id" + ] + } + }, + { + "dimension.attribute": { + "name": "sku", + "@of": "Product.sku" + } + }, + { + "measure.aggregate": { + "name": "products", + "@agg": "count", + "@of": "Product.id" + } + } + ] + } + }, + { + "object.value": { + "name": "Price", + "@object": "com.acme.catalog.Price", + "@objectAdapter": "com.acme.catalog.PriceAdapter", + "children": [ + { + "field.string": { + "name": "currency" + } + } + ] + } + }, + { + "object.projection": { + "name": "ProductSummary", + "@object": "com.acme.catalog.ProductSummary", + "@objectAdapter": "com.acme.catalog.ProductSummaryAdapter", + "children": [ + { + "source.rdb": { + "@kind": "view", + "@view": "v_product_summary" + } + }, + { + "field.string": { + "name": "sku" + } + } + ] + } + }, + { + "object.report": { + "name": "ProductCounts", + "@object": "com.acme.catalog.ProductCounts", + "@objectAdapter": "com.acme.catalog.ProductCountsAdapter", + "@from": "Product", + "@dimensions": [ + "sku" + ], + "@measures": [ + "products" + ], + "children": [ + { + "source.rdb": { + "@kind": "view", + "@view": "v_product_counts" + } + } + ] + } + } + ] + } +} diff --git a/fixtures/conformance/view-kind1-controls/expected.json b/fixtures/conformance/view-kind1-controls/expected.json new file mode 100644 index 0000000000..6da2060ace --- /dev/null +++ b/fixtures/conformance/view-kind1-controls/expected.json @@ -0,0 +1,193 @@ +{ + "metadata.root": { + "package": "acme::catalog", + "children": [ + { + "object.entity": { + "name": "Product", + "children": [ + { + "field.long": { + "name": "id" + } + }, + { + "field.string": { + "name": "checkboxValue", + "children": [ + { + "view.checkbox": { + "name": "form" + } + } + ] + } + }, + { + "field.string": { + "name": "dateValue", + "children": [ + { + "view.date": { + "name": "form" + } + } + ] + } + }, + { + "field.string": { + "name": "dropdownValue", + "children": [ + { + "view.dropdown": { + "name": "form" + } + } + ] + } + }, + { + "field.string": { + "name": "hiddenValue", + "children": [ + { + "view.hidden": { + "name": "form" + } + } + ] + } + }, + { + "field.string": { + "name": "hotlinkValue", + "children": [ + { + "view.hotlink": { + "name": "form" + } + } + ] + } + }, + { + "field.string": { + "name": "monthValue", + "children": [ + { + "view.month": { + "name": "form" + } + } + ] + } + }, + { + "field.string": { + "name": "numberValue", + "children": [ + { + "view.number": { + "name": "form" + } + } + ] + } + }, + { + "field.string": { + "name": "passwordValue", + "children": [ + { + "view.password": { + "name": "form" + } + } + ] + } + }, + { + "field.string": { + "name": "radioValue", + "children": [ + { + "view.radio": { + "name": "form" + } + } + ] + } + }, + { + "field.string": { + "name": "textValue", + "children": [ + { + "view.text": { + "name": "form" + } + } + ] + } + }, + { + "field.string": { + "name": "webValue", + "children": [ + { + "view.web": { + "name": "form" + } + } + ] + } + }, + { + "field.string": { + "name": "notes", + "children": [ + { + "view.textarea": { + "name": "form", + "@rows": 6 + } + } + ] + } + }, + { + "field.string": { + "name": "coverKey", + "@maxLength": 80, + "children": [ + { + "view.image": { + "name": "form", + "@accept": [ + "image/jpeg", + "image/png" + ], + "@aspectRatio": 1.5, + "@maxBytes": 10485760, + "@maxEdge": 2000, + "@store": "photos" + } + } + ] + } + }, + { + "identity.primary": { + "name": "pk", + "@fields": [ + "id" + ] + } + } + ] + } + } + ] + } +} diff --git a/fixtures/conformance/view-kind1-controls/input/meta.catalog.json b/fixtures/conformance/view-kind1-controls/input/meta.catalog.json new file mode 100644 index 0000000000..7e5b217bae --- /dev/null +++ b/fixtures/conformance/view-kind1-controls/input/meta.catalog.json @@ -0,0 +1,193 @@ +{ + "metadata.root": { + "package": "acme::catalog", + "children": [ + { + "object.entity": { + "name": "Product", + "children": [ + { + "field.long": { + "name": "id" + } + }, + { + "field.string": { + "name": "checkboxValue", + "children": [ + { + "view.checkbox": { + "name": "form" + } + } + ] + } + }, + { + "field.string": { + "name": "dateValue", + "children": [ + { + "view.date": { + "name": "form" + } + } + ] + } + }, + { + "field.string": { + "name": "dropdownValue", + "children": [ + { + "view.dropdown": { + "name": "form" + } + } + ] + } + }, + { + "field.string": { + "name": "hiddenValue", + "children": [ + { + "view.hidden": { + "name": "form" + } + } + ] + } + }, + { + "field.string": { + "name": "hotlinkValue", + "children": [ + { + "view.hotlink": { + "name": "form" + } + } + ] + } + }, + { + "field.string": { + "name": "monthValue", + "children": [ + { + "view.month": { + "name": "form" + } + } + ] + } + }, + { + "field.string": { + "name": "numberValue", + "children": [ + { + "view.number": { + "name": "form" + } + } + ] + } + }, + { + "field.string": { + "name": "passwordValue", + "children": [ + { + "view.password": { + "name": "form" + } + } + ] + } + }, + { + "field.string": { + "name": "radioValue", + "children": [ + { + "view.radio": { + "name": "form" + } + } + ] + } + }, + { + "field.string": { + "name": "textValue", + "children": [ + { + "view.text": { + "name": "form" + } + } + ] + } + }, + { + "field.string": { + "name": "webValue", + "children": [ + { + "view.web": { + "name": "form" + } + } + ] + } + }, + { + "field.string": { + "name": "notes", + "children": [ + { + "view.textarea": { + "name": "form", + "@rows": 6 + } + } + ] + } + }, + { + "field.string": { + "name": "coverKey", + "@maxLength": 80, + "children": [ + { + "view.image": { + "name": "form", + "@aspectRatio": 1.5, + "@maxEdge": 2000, + "@store": "photos", + "@accept": [ + "image/jpeg", + "image/png" + ], + "@maxBytes": 10485760 + } + } + ] + } + }, + { + "identity.primary": { + "name": "pk", + "@fields": [ + "id" + ] + } + } + ] + } + } + ] + } +} diff --git a/fixtures/metamodel-docs/expected/INDEX.md b/fixtures/metamodel-docs/expected/INDEX.md index 1d5bb0f58f..1a81c10049 100644 --- a/fixtures/metamodel-docs/expected/INDEX.md +++ b/fixtures/metamodel-docs/expected/INDEX.md @@ -91,4 +91,17 @@ children and the cardinality of that subtype. Documentation attributes | `validator.required` | Fails when the value is null (NOT NULL). Equivalent to @required on the owning field: on a non-array string, generated wire-tier input validation also rejects the empty string by default unless an explicit validator.length @min: 0 opts back to presence-only. | [types/validator.md#validatorrequired](types/validator.md#validatorrequired) | | `validator.requiredWhen` | One-directional conditional presence: when the gating field (@when) equals @equals, the target field (@field) must be present (NOT NULL); otherwise @field is unconstrained. Mirrors JSON Schema dependentRequired / Rails validates_presence_of :x, if:. Entity-scoped; references fields by name. | [types/validator.md#validatorrequiredwhen](types/validator.md#validatorrequiredwhen) | | `view.base` | Abstract view base — the shared root subtype for field-level UI/render hints. A view declares how a field's value is rendered or edited; the base carries no attrs of its own. Not authored directly: a `view.base` node fails to load (ERR_ABSTRACT_SUBTYPE_AUTHORED) — this subtype is a registry anchor concrete subtypes inherit from, never a node in a document. | [types/view.md#viewbase](types/view.md#viewbase) | +| `view.checkbox` | Checkbox selection control. | [types/view.md#viewcheckbox](types/view.md#viewcheckbox) | | `view.currency` | Currency display formatting (locale-aware via @locale). | [types/view.md#viewcurrency](types/view.md#viewcurrency) | +| `view.date` | Date picker / date display. | [types/view.md#viewdate](types/view.md#viewdate) | +| `view.dropdown` | Single-select dropdown control. | [types/view.md#viewdropdown](types/view.md#viewdropdown) | +| `view.hidden` | Not rendered; carried but not shown. | [types/view.md#viewhidden](types/view.md#viewhidden) | +| `view.hotlink` | Renders the value as a clickable link. | [types/view.md#viewhotlink](types/view.md#viewhotlink) | +| `view.image` | Image upload/display control; the field stores an opaque storage key (field.string). | [types/view.md#viewimage](types/view.md#viewimage) | +| `view.month` | Month picker / month display. | [types/view.md#viewmonth](types/view.md#viewmonth) | +| `view.number` | Numeric input control. | [types/view.md#viewnumber](types/view.md#viewnumber) | +| `view.password` | Masked input for sensitive values. | [types/view.md#viewpassword](types/view.md#viewpassword) | +| `view.radio` | Radio-button selection control. | [types/view.md#viewradio](types/view.md#viewradio) | +| `view.text` | Single-line text input/display. | [types/view.md#viewtext](types/view.md#viewtext) | +| `view.textarea` | Multi-line text area. | [types/view.md#viewtextarea](types/view.md#viewtextarea) | +| `view.web` | Abstract base for web-rendered views. | [types/view.md#viewweb](types/view.md#viewweb) | diff --git a/fixtures/metamodel-docs/expected/providers.md b/fixtures/metamodel-docs/expected/providers.md index a4d72cca64..e2a4b48491 100644 --- a/fixtures/metamodel-docs/expected/providers.md +++ b/fixtures/metamodel-docs/expected/providers.md @@ -13,7 +13,7 @@ provider owns. This is the ownership lens over the same vocabulary Core metaobjects metamodel types and subtypes. -**Owns (registers):** `attr.base`, `attr.boolean`, `attr.class`, `attr.double`, `attr.expression`, `attr.filter`, `attr.int`, `attr.intMap`, `attr.long`, `attr.properties`, `attr.string`, `field.base`, `field.boolean`, `field.currency`, `field.date`, `field.decimal`, `field.double`, `field.duration`, `field.enum`, `field.float`, `field.inet`, `field.int`, `field.long`, `field.map`, `field.object`, `field.string`, `field.time`, `field.timestamp`, `field.uri`, `field.uuid`, `identity.primary`, `identity.reference`, `identity.secondary`, `layout.base`, `layout.dataGrid`, `object.base`, `object.entity`, `object.projection`, `object.report`, `object.value`, `origin.aggregate`, `origin.base`, `origin.computed`, `origin.first`, `origin.passthrough`, `relationship.aggregation`, `relationship.association`, `relationship.base`, `relationship.composition`, `source.base`, `source.rdb`, `template.base`, `template.output`, `template.prompt`, `template.toolcall`, `validator.array`, `validator.atLeastOne`, `validator.base`, `validator.comparison`, `validator.exactlyOne`, `validator.length`, `validator.numeric`, `validator.presentIff`, `validator.regex`, `validator.required`, `validator.requiredWhen`, `view.base`, `view.currency` +**Owns (registers):** `attr.base`, `attr.boolean`, `attr.class`, `attr.double`, `attr.expression`, `attr.filter`, `attr.int`, `attr.intMap`, `attr.long`, `attr.properties`, `attr.string`, `field.base`, `field.boolean`, `field.currency`, `field.date`, `field.decimal`, `field.double`, `field.duration`, `field.enum`, `field.float`, `field.inet`, `field.int`, `field.long`, `field.map`, `field.object`, `field.string`, `field.time`, `field.timestamp`, `field.uri`, `field.uuid`, `identity.primary`, `identity.reference`, `identity.secondary`, `layout.base`, `layout.dataGrid`, `object.base`, `object.entity`, `object.projection`, `object.report`, `object.value`, `origin.aggregate`, `origin.base`, `origin.computed`, `origin.first`, `origin.passthrough`, `relationship.aggregation`, `relationship.association`, `relationship.base`, `relationship.composition`, `source.base`, `source.rdb`, `template.base`, `template.output`, `template.prompt`, `template.toolcall`, `validator.array`, `validator.atLeastOne`, `validator.base`, `validator.comparison`, `validator.exactlyOne`, `validator.length`, `validator.numeric`, `validator.presentIff`, `validator.regex`, `validator.required`, `validator.requiredWhen`, `view.base`, `view.checkbox`, `view.currency`, `view.date`, `view.dropdown`, `view.hidden`, `view.hotlink`, `view.image`, `view.month`, `view.number`, `view.password`, `view.radio`, `view.text`, `view.textarea`, `view.web` **Contributes attributes:** @@ -29,6 +29,7 @@ Core metaobjects metamodel types and subtypes. - `identity.primary`: `@fields`, `@generation` - `identity.reference`: `@enforce`, `@fields`, `@references` - `identity.secondary`: `@fields` +- `object.base`: `@object`, `@objectAdapter` - `object.entity`: `@dbSetName`, `@discriminator`, `@discriminatorValue` - `object.projection`: `@dbSetName`, `@filter` - `object.report`: `@dbSetName`, `@dimensions`, `@filter`, `@from`, `@measures`, `@segment`, `@spine` @@ -156,7 +157,7 @@ UI/query-surface domain — @filterable / @sortable / @sortableDefaultOrder fiel ## metaobjects-ui-web -TS-web presentation view attrs — @rows (view.textarea) and the view.image control attrs. Applied only in TypeScript; the non-TS ports mirror the spec file but never apply this provider (the view subtypes are TS-web presentation-only). +Web presentation view attrs — @rows (view.textarea) and the view.image control attrs. Every port applies this provider and loads them strictly; only TypeScript acts on them so far. **Contributes attributes:** diff --git a/fixtures/metamodel-docs/expected/types/object.md b/fixtures/metamodel-docs/expected/types/object.md index e02f41c316..cb69c9ca09 100644 --- a/fixtures/metamodel-docs/expected/types/object.md +++ b/fixtures/metamodel-docs/expected/types/object.md @@ -18,7 +18,10 @@ Abstract object base — the shared root subtype that concrete object subtypes ( **Attributes** -_No subtype-specific attributes._ +| Attribute | Type | Required | Default | Allowed values | Provider | Description | +| --- | --- | --- | --- | --- | --- | --- | +| `@object` | string | no | | | metaobjects-core-types | The native class an object binds to (ADR-0001), in place of its default runtime class: on the JVM, a fully-qualified class name. Cross-port vocabulary only Java implements so far; every port loads and type-checks it, and the others do not act on it yet. | +| `@objectAdapter` | string | no | | | metaobjects-core-types | JVM-only (ADR-0005): the fully-qualified name of an ObjectAdapter that takes over value access for this object's instances. Every port loads and type-checks it; only Java and Kotlin act on it. | **Allowed children** @@ -46,6 +49,8 @@ An object that owns its data: own identity, writable sources, and lifecycle. The | `@dbSetName` | string | no | | | metaobjects-core-types | C#-only (EF Core): the DbSet property name the generated context gives this object, in place of the plural derived from its name. Set it when two objects in one generated context would otherwise claim the same property. Every port loads and type-checks it; only C# acts on it. | | `@discriminator` | string | no | | | metaobjects-core-types | FR-014: names the field on this entity (resolvable via extends:) that holds the subtype-discriminator value. Subtypes of this entity declare @discriminatorValue to bind their rows to a discriminator value. The discriminator field itself is an ordinary field declaration (typically field.enum or field.int / field.string). | | `@discriminatorValue` | string | no | | | metaobjects-core-types | FR-014: on a subtype of an entity with @discriminator — the value that identifies rows of this subtype in the shared discriminator field. Wire form is always a string; the underlying field's subtype (enum / int / string) controls codegen + storage coercion. Required on every concrete subtype of a discriminated entity. | +| `@object` | string | no | | | metaobjects-core-types | The native class an object binds to (ADR-0001), in place of its default runtime class: on the JVM, a fully-qualified class name. Cross-port vocabulary only Java implements so far; every port loads and type-checks it, and the others do not act on it yet. | +| `@objectAdapter` | string | no | | | metaobjects-core-types | JVM-only (ADR-0005): the fully-qualified name of an ObjectAdapter that takes over value access for this object's instances. Every port loads and type-checks it; only Java and Kotlin act on it. | **Allowed children** @@ -77,6 +82,8 @@ A derived read-only representation of entities. Its fields are extends-bound / o | --- | --- | --- | --- | --- | --- | --- | | `@dbSetName` | string | no | | | metaobjects-core-types | C#-only (EF Core): the DbSet property name the generated context gives this object, in place of the plural derived from its name. Set it when two objects in one generated context would otherwise claim the same property. Every port loads and type-checks it; only C# acts on it. | | `@filter` | filter | no | | | metaobjects-core-types | Optional row-scope predicate (a portable attr.filter object: eq/ne/gt/gte/lt/lte/like/in/isNull with and/or, desugared to { field: { op: value } } at parse time) selecting which rows the view returns — lowered to an outer SQL WHERE. Resolves against the projection's own declared fields; an aggregate-derived field is not addressable (fail-closed). | +| `@object` | string | no | | | metaobjects-core-types | The native class an object binds to (ADR-0001), in place of its default runtime class: on the JVM, a fully-qualified class name. Cross-port vocabulary only Java implements so far; every port loads and type-checks it, and the others do not act on it yet. | +| `@objectAdapter` | string | no | | | metaobjects-core-types | JVM-only (ADR-0005): the fully-qualified name of an ObjectAdapter that takes over value access for this object's instances. Every port loads and type-checks it; only Java and Kotlin act on it. | **Allowed children** @@ -104,6 +111,8 @@ A declared report (FR-044): a fixed combination of dimensions and measures of ON | `@filter` | filter | no | | | metaobjects-core-types | Optional row scope over @from's fields; may use relative-date values. | | `@from` | string | yes | | | metaobjects-core-types | The object.entity whose rows the report aggregates. | | `@measures` | string[] | yes | | | metaobjects-core-types | Measure names of @from. | +| `@object` | string | no | | | metaobjects-core-types | The native class an object binds to (ADR-0001), in place of its default runtime class: on the JVM, a fully-qualified class name. Cross-port vocabulary only Java implements so far; every port loads and type-checks it, and the others do not act on it yet. | +| `@objectAdapter` | string | no | | | metaobjects-core-types | JVM-only (ADR-0005): the fully-qualified name of an ObjectAdapter that takes over value access for this object's instances. Every port loads and type-checks it; only Java and Kotlin act on it. | | `@segment` | string | no | | | metaobjects-core-types | Optional segment of @from scoping the rows. | | `@spine` | string | no | | | metaobjects-core-types | Optional to-one path from @from to the entity whose rows supply the report's rows (e.g. 'Purchase.program'), written like a dimension's @via. With it the report has one row per distinct dimension tuple among THAT entity's rows, including the ones no row of @from refers to: a count there is 0 and any other measure is null unless it declares @default. Every listed dimension must be reached through this path. @segment and @filter still scope the rows of @from and never remove a row. A row of @from whose reference is null or matches nothing is in no row of the report. | @@ -131,6 +140,8 @@ A value object — pure shape with NO identity and NO source, ever. Constructed | Attribute | Type | Required | Default | Allowed values | Provider | Description | | --- | --- | --- | --- | --- | --- | --- | | `@normalize` | string | no | `strip` | `none`, `collapse`, `strip` | metaobjects-prompt | ASCII normalization mode for tolerant enum extract (none\|collapse\|strip, default strip). On field.enum it is per-field; on object.value it is the default for the object's enum fields. | +| `@object` | string | no | | | metaobjects-core-types | The native class an object binds to (ADR-0001), in place of its default runtime class: on the JVM, a fully-qualified class name. Cross-port vocabulary only Java implements so far; every port loads and type-checks it, and the others do not act on it yet. | +| `@objectAdapter` | string | no | | | metaobjects-core-types | JVM-only (ADR-0005): the fully-qualified name of an ObjectAdapter that takes over value access for this object's instances. Every port loads and type-checks it; only Java and Kotlin act on it. | **Allowed children** diff --git a/fixtures/metamodel-docs/expected/types/view.md b/fixtures/metamodel-docs/expected/types/view.md index 1615655f98..edc362ecd3 100644 --- a/fixtures/metamodel-docs/expected/types/view.md +++ b/fixtures/metamodel-docs/expected/types/view.md @@ -24,6 +24,22 @@ _No subtype-specific attributes._ _No structural children._ +### view.checkbox + +Checkbox selection control. + +**Owning provider:** metaobjects-core-types + +**Implemented in:** typescript so far — every port loads and type-checks it; the others do not act on it yet. + +**Attributes** + +_No subtype-specific attributes._ + +**Allowed children** + +_No structural children._ + ### view.currency Currency display formatting (locale-aware via @locale). @@ -40,3 +56,203 @@ Currency display formatting (locale-aware via @locale). _No structural children._ +### view.date + +Date picker / date display. + +**Owning provider:** metaobjects-core-types + +**Implemented in:** typescript so far — every port loads and type-checks it; the others do not act on it yet. + +**Attributes** + +_No subtype-specific attributes._ + +**Allowed children** + +_No structural children._ + +### view.dropdown + +Single-select dropdown control. + +**Owning provider:** metaobjects-core-types + +**Implemented in:** typescript so far — every port loads and type-checks it; the others do not act on it yet. + +**Attributes** + +_No subtype-specific attributes._ + +**Allowed children** + +_No structural children._ + +### view.hidden + +Not rendered; carried but not shown. + +**Owning provider:** metaobjects-core-types + +**Implemented in:** typescript so far — every port loads and type-checks it; the others do not act on it yet. + +**Attributes** + +_No subtype-specific attributes._ + +**Allowed children** + +_No structural children._ + +### view.hotlink + +Renders the value as a clickable link. + +**Owning provider:** metaobjects-core-types + +**Implemented in:** typescript so far — every port loads and type-checks it; the others do not act on it yet. + +**Attributes** + +_No subtype-specific attributes._ + +**Allowed children** + +_No structural children._ + +### view.image + +Image upload/display control; the field stores an opaque storage key (field.string). + +**Owning provider:** metaobjects-core-types + +**Implemented in:** typescript so far — every port loads and type-checks it; the others do not act on it yet. + +**Attributes** + +| Attribute | Type | Required | Default | Allowed values | Provider | Description | +| --- | --- | --- | --- | --- | --- | --- | +| `@accept` | string[] | no | | | metaobjects-ui-web | Accepted MIME types (client guard; the server re-enforces). | +| `@aspectRatio` | double | no | | | metaobjects-ui-web | Crop aspect ratio (width / height). Omit for freeform. | +| `@maxBytes` | int | no | | | metaobjects-ui-web | Client-side size ceiling in bytes. | +| `@maxEdge` | int | no | | | metaobjects-ui-web | Longest-edge bound in px for the re-encoded output. | +| `@store` | string | no | | | metaobjects-ui-web | Opaque storage-namespace hint passed to the upload adapter (not infrastructure). | + +**Allowed children** + +_No structural children._ + +### view.month + +Month picker / month display. + +**Owning provider:** metaobjects-core-types + +**Implemented in:** typescript so far — every port loads and type-checks it; the others do not act on it yet. + +**Attributes** + +_No subtype-specific attributes._ + +**Allowed children** + +_No structural children._ + +### view.number + +Numeric input control. + +**Owning provider:** metaobjects-core-types + +**Implemented in:** typescript so far — every port loads and type-checks it; the others do not act on it yet. + +**Attributes** + +_No subtype-specific attributes._ + +**Allowed children** + +_No structural children._ + +### view.password + +Masked input for sensitive values. + +**Owning provider:** metaobjects-core-types + +**Implemented in:** typescript so far — every port loads and type-checks it; the others do not act on it yet. + +**Attributes** + +_No subtype-specific attributes._ + +**Allowed children** + +_No structural children._ + +### view.radio + +Radio-button selection control. + +**Owning provider:** metaobjects-core-types + +**Implemented in:** typescript so far — every port loads and type-checks it; the others do not act on it yet. + +**Attributes** + +_No subtype-specific attributes._ + +**Allowed children** + +_No structural children._ + +### view.text + +Single-line text input/display. + +**Owning provider:** metaobjects-core-types + +**Implemented in:** typescript so far — every port loads and type-checks it; the others do not act on it yet. + +**Attributes** + +_No subtype-specific attributes._ + +**Allowed children** + +_No structural children._ + +### view.textarea + +Multi-line text area. + +**Owning provider:** metaobjects-core-types + +**Implemented in:** typescript so far — every port loads and type-checks it; the others do not act on it yet. + +**Attributes** + +| Attribute | Type | Required | Default | Allowed values | Provider | Description | +| --- | --- | --- | --- | --- | --- | --- | +| `@rows` | int | no | | | metaobjects-ui-web | Visible row count for the generated