Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .changeset/28560-field-patch-slot.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
---
'@objectstack/spec': minor
---
Expand All @@ -16,7 +16,7 @@
industry: {
label: 'Sector',
inlineHelpText: 'The market the account sells into',
options: { tech: { label: 'Technology' } },
options: { technology: { label: 'Tech' } },
},
},
}]
Expand Down
2 changes: 1 addition & 1 deletion .changeset/28565-field-patch-applied.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
---
'@objectstack/objectql': minor
'@objectstack/metadata-core': minor
Expand All @@ -17,7 +17,7 @@
objectExtensions: [{
extend: 'crm_account',
fieldPatches: {
industry: { label: 'Sector', inlineHelpText: 'The market the account sells into', options: { tech: { label: 'Technology' } } },
industry: { label: 'Sector', inlineHelpText: 'The market the account sells into', options: { technology: { label: 'Tech' } } },
},
}]
```
Expand Down
10 changes: 10 additions & 0 deletions .changeset/28803-field-patches-example.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@objectstack/spec': patch
---

docs(spec): the documented `fieldPatches` example keys its option by a value `crm_account.industry` really stores

Clause-②: no
Metadata-protocol: none

The `fieldPatches` description, its TSDoc example and the refusal text for an option list under `options` showed `options: { tech: { label: 'Technology' } }`. `crm_account.industry` stores `technology`, not `tech`, so a copy of that example was refused at `os validate` and at install as naming an option the field does not have. The example now reads `options: { technology: { label: 'Tech' } }`. Prose only: no schema accepts or refuses anything differently.
2 changes: 1 addition & 1 deletion content/docs/data-modeling/object-extensions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export const AccountWordingExtension = defineObjectExtension({
industry: {
label: 'Sector',
inlineHelpText: 'The market the account sells into.',
options: { tech: { label: 'Technology' } }, // addressed by the stored value
options: { technology: { label: 'Tech' } }, // addressed by the stored value
},
},
});
Expand Down
2 changes: 1 addition & 1 deletion content/docs/references/data/object.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,7 @@ const result = ApiMethod.parse(data);
| :--- | :--- | :--- | :--- |
| **extend** | `string` | ✅ | Target object name (FQN) to extend |
| **fields** | `Record<string, { name?: string; label?: string; type: Enum<'text' \| 'textarea' \| 'email' \| 'url' \| 'phone' \| 'password' \| 'secret' \| …>; description?: string; … }>` | optional | Fields to add/override |
| **fieldPatches** | `Record<string, { label?: string; description?: string; inlineHelpText?: string; placeholder?: string; … }>` | optional | Display patches of the target object's own fields, keyed by field name: change a vendor field's display properties (BASE_FIELD_DISPLAY_WHITELIST: label, description, help text, placeholder, option labels) without taking the field over, so its type, values and rules stay the vendor's and its upgrades still apply (ADR-0146 D10). Applied by the registry merge (`mergeObjectDefinitions`) after the additive merges, on every object read: a tenant's own text keeps winning, and between two extensions the higher `priority` wins. A patch naming a field or option value the target does not have is refused at install and by `os validate`. Example: `fieldPatches: { industry: { label: 'Sector', inlineHelpText: 'The market the account sells into', options: { tech: { label: 'Technology' } } } }`. |
| **fieldPatches** | `Record<string, { label?: string; description?: string; inlineHelpText?: string; placeholder?: string; … }>` | optional | Display patches of the target object's own fields, keyed by field name: change a vendor field's display properties (BASE_FIELD_DISPLAY_WHITELIST: label, description, help text, placeholder, option labels) without taking the field over, so its type, values and rules stay the vendor's and its upgrades still apply (ADR-0146 D10). Applied by the registry merge (`mergeObjectDefinitions`) after the additive merges, on every object read: a tenant's own text keeps winning, and between two extensions the higher `priority` wins. A patch naming a field or option value the target does not have is refused at install and by `os validate`. Example: `fieldPatches: { industry: { label: 'Sector', inlineHelpText: 'The market the account sells into', options: { technology: { label: 'Tech' } } } }`. |
| **label** | `string` | optional | Override label for the extended object |
| **pluralLabel** | `string` | optional | Override plural label for the extended object |
| **description** | `string` | optional | Override description for the extended object |
Expand Down
8 changes: 4 additions & 4 deletions packages/spec/src/data/object.zod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4835,7 +4835,7 @@ const FieldDisplayPatchSchema = lazySchema(() => {
error: (issue) =>
issue.code === 'invalid_type' && Array.isArray(issue.input)
? 'A field patch\'s `options` is a map keyed by each option\'s stored value — ' +
'`options: { tech: { label: \'Technology\' } }` — not the field\'s option list: which options ' +
'`options: { technology: { label: \'Tech\' } }` — not the field\'s option list: which options ' +
'exist stays the vendor\'s (ADR-0146 D6).'
: undefined,
}).optional().describe(
Expand Down Expand Up @@ -4879,7 +4879,7 @@ function refuseExtensionFieldPatchKeys(fieldPatches: unknown, ctx: z.RefinementC
* fields: { sales_stage: Field.select([...]) },
* // A base field's display properties only (ADR-0146 D10), applied by the
* // registry merge (`mergeObjectDefinitions`) — see `fieldPatches`.
* fieldPatches: { industry: { label: 'Sector', options: { tech: { label: 'Technology' } } } },
* fieldPatches: { industry: { label: 'Sector', options: { technology: { label: 'Tech' } } } },
* }]
* ```
*/
Expand Down Expand Up @@ -4964,8 +4964,8 @@ export const ObjectExtensionSchema = lazySchema(() => strictObject({
'the additive merges, on every object read: a tenant\'s own text keeps winning, and between two ' +
'extensions the higher `priority` wins. A patch naming a field or option value the target does not ' +
'have is refused at install and by `os validate`. Example: `fieldPatches: { industry: { label: ' +
'\'Sector\', inlineHelpText: \'The market the account sells into\', options: { tech: { label: ' +
'\'Technology\' } } } }`.',
'\'Sector\', inlineHelpText: \'The market the account sells into\', options: { technology: { label: ' +
'\'Tech\' } } } }`.',
),

/** Override label */
Expand Down
Loading