@bridge_gpt/mcp-server 0.2.19 → 0.2.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -3
- package/build/agents.generated.js +1 -1
- package/build/commands.generated.js +4 -3
- package/build/conductor/local-merge.js +458 -95
- package/build/estimate-epic.js +84 -0
- package/build/executor/job-runner.js +151 -17
- package/build/executor/merge-job.js +84 -10
- package/build/executor/worker-finalization.js +98 -18
- package/build/index.js +1843 -401
- package/build/pipelines.generated.js +16 -20
- package/build/readme.generated.js +1 -1
- package/build/review-tickets.js +15 -5
- package/build/sfcc/client.js +192 -50
- package/build/sfcc/ocapi-write-faults.js +94 -0
- package/build/sfcc/permissions.js +7 -22
- package/build/sfcc/register.js +9 -0
- package/build/sfcc/write-grants.js +80 -0
- package/build/sfcc/write-guard.js +39 -0
- package/build/sfcc/write-result.js +47 -0
- package/build/sfcc/write-tool-common.js +85 -0
- package/build/sfcc/writes-custom-object-def.js +141 -0
- package/build/sfcc/writes-object-attribute-payloads.js +97 -0
- package/build/sfcc/writes-site-preference-payloads.js +59 -0
- package/build/sfcc/writes-site-preference.js +96 -0
- package/build/sfcc/writes-system-object-payloads.js +213 -0
- package/build/sfcc/writes-system-object.js +348 -0
- package/build/sfcc/writes.js +66 -0
- package/build/version.generated.js +1 -1
- package/package.json +3 -3
- package/pipelines/idea-to-ticket.json +7 -0
- package/pipelines/review-ticket.json +5 -18
- package/public/css/main.min.css +1583 -117
- package/public/css/main.min.css.map +1 -1
- package/public/js/main.min.js +2792 -449
- package/public/js/main.min.js.map +1 -1
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure payload builders + schemas for OCAPI site-preference value writes
|
|
3
|
+
* (BAPI-584).
|
|
4
|
+
*
|
|
5
|
+
* This module performs NO network calls. It keeps site-preference request-body
|
|
6
|
+
* construction decoupled from OCAPI transport (client.ts). The write endpoint
|
|
7
|
+
* (`PATCH /site_preferences/preference_groups/{group}/{instance}`) accepts a
|
|
8
|
+
* FLAT map of custom preference ids (`c_`-prefixed) to primitive/set values —
|
|
9
|
+
* there is no wrapper object such as `{ values: ... }`.
|
|
10
|
+
*/
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Value + map schemas
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
/**
|
|
16
|
+
* Accepted site-preference value shapes: string, finite number (int/double),
|
|
17
|
+
* boolean, or a set-of-string (string[]). Nested objects and other shapes are
|
|
18
|
+
* rejected before any OCAPI call.
|
|
19
|
+
*/
|
|
20
|
+
export const sitePreferenceValueSchema = z.union([
|
|
21
|
+
z.string(),
|
|
22
|
+
z.number().finite(),
|
|
23
|
+
z.boolean(),
|
|
24
|
+
z.array(z.string()),
|
|
25
|
+
]);
|
|
26
|
+
/**
|
|
27
|
+
* A flat map of custom preference ids to values. Every key must be
|
|
28
|
+
* `c_`-prefixed (custom preferences only) and the map must be non-empty.
|
|
29
|
+
*/
|
|
30
|
+
export const sitePreferenceValuesPatchBodySchema = z
|
|
31
|
+
.record(z.string(), sitePreferenceValueSchema)
|
|
32
|
+
.superRefine((values, ctx) => {
|
|
33
|
+
const keys = Object.keys(values);
|
|
34
|
+
if (keys.length === 0) {
|
|
35
|
+
ctx.addIssue({
|
|
36
|
+
code: z.ZodIssueCode.custom,
|
|
37
|
+
message: "At least one preference value is required.",
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
for (const key of keys) {
|
|
41
|
+
if (!key.startsWith("c_")) {
|
|
42
|
+
ctx.addIssue({
|
|
43
|
+
code: z.ZodIssueCode.custom,
|
|
44
|
+
path: [key],
|
|
45
|
+
message: `Preference id '${key}' must be a custom preference starting with 'c_'.`,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
// Builder (pure)
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
/**
|
|
54
|
+
* Build the site-preference value PATCH payload — a shallow copy of the flat
|
|
55
|
+
* map exactly as OCAPI expects it, with no wrapper object.
|
|
56
|
+
*/
|
|
57
|
+
export function buildSitePreferenceValuesPatchPayload(values) {
|
|
58
|
+
return { ...values };
|
|
59
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SFCC site-preference value write tool (BAPI-584).
|
|
3
|
+
*
|
|
4
|
+
* Implements:
|
|
5
|
+
* site_preference_values_set — PATCH /site_preferences/preference_groups/{group}/sandbox
|
|
6
|
+
*
|
|
7
|
+
* Sets custom site-preference VALUES through the OCAPI Data API. Sandbox-only:
|
|
8
|
+
* the value endpoint would otherwise accept `production`, so the `{instance}`
|
|
9
|
+
* segment is forced to the `sandbox` literal AFTER the shared sandbox guard has
|
|
10
|
+
* validated the requested instance. The body is a FLAT map of `c_`-prefixed
|
|
11
|
+
* custom preference ids to primitive/set-of-string values. Mirrors
|
|
12
|
+
* reads-site-preference.ts.
|
|
13
|
+
*
|
|
14
|
+
* The handler is call-time gated by `withSfccGate`, sandbox-guarded, and routes
|
|
15
|
+
* its OCAPI result through `formatOcapiWriteToolResult` (403 → paste-ready grant
|
|
16
|
+
* JSON; a bad group surfaces as 404 CustomPreferenceGroupNotFoundException).
|
|
17
|
+
*/
|
|
18
|
+
import { z } from "zod";
|
|
19
|
+
import { ocapiPatchDirect } from "./client.js";
|
|
20
|
+
import { withSfccGate } from "./tool-wrapper.js";
|
|
21
|
+
import { rejectIfNotSandboxForWrite } from "./write-guard.js";
|
|
22
|
+
import { formatOcapiWriteToolResult } from "./write-result.js";
|
|
23
|
+
import { sitePreferenceValuesPatchBodySchema, buildSitePreferenceValuesPatchPayload, } from "./writes-site-preference-payloads.js";
|
|
24
|
+
import { WRITE_ANNOTATIONS, encodedSegment, preTransportErrorEnvelope, unexpectedEnvelope, } from "./write-tool-common.js";
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// Input schema
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
// Mirror reads-site-preference.ts so callers see the same instance enum, while
|
|
29
|
+
// the write remains sandbox-only (enforced by the guard + the literal path).
|
|
30
|
+
const INSTANCE_ENUM = z.enum(["staging", "development", "sandbox", "production"]);
|
|
31
|
+
const INSTANCE_DESCRIBE = "OCAPI instance context. v1 supports the 'sandbox' context only; any other " +
|
|
32
|
+
"value is rejected before OCAPI is called. Defaults to 'sandbox'.";
|
|
33
|
+
const sitePreferenceValuesSetInput = z.object({
|
|
34
|
+
group: z.string().describe("Custom site preference group id, e.g. 'LLMIntegration'."),
|
|
35
|
+
instance: INSTANCE_ENUM.optional().default("sandbox").describe(INSTANCE_DESCRIBE),
|
|
36
|
+
values: sitePreferenceValuesPatchBodySchema.describe("Flat map of c_-prefixed preference ids to values (string, number, boolean, or string[])."),
|
|
37
|
+
});
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
// Path builder
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
/**
|
|
42
|
+
* Build the site-preference group PATCH path. The `{instance}` segment is the
|
|
43
|
+
* `sandbox` literal — a non-sandbox instance is rejected by the guard before
|
|
44
|
+
* this is called, so a non-sandbox value can never leak into transport.
|
|
45
|
+
*/
|
|
46
|
+
export function sitePreferenceGroupPath(group) {
|
|
47
|
+
return `/site_preferences/preference_groups/${encodedSegment(group)}/sandbox`;
|
|
48
|
+
}
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
// Handler
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
export function buildSitePreferenceValuesSetHandler(gateDeps) {
|
|
53
|
+
return withSfccGate(gateDeps, async (args, credentials) => {
|
|
54
|
+
let parsed;
|
|
55
|
+
try {
|
|
56
|
+
parsed = sitePreferenceValuesSetInput.parse(args);
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
return preTransportErrorEnvelope(err);
|
|
60
|
+
}
|
|
61
|
+
const guard = rejectIfNotSandboxForWrite(parsed.instance);
|
|
62
|
+
if (guard)
|
|
63
|
+
return guard;
|
|
64
|
+
const path = sitePreferenceGroupPath(parsed.group);
|
|
65
|
+
const body = buildSitePreferenceValuesPatchPayload(parsed.values);
|
|
66
|
+
try {
|
|
67
|
+
// Direct PATCH (no ETag round trip): the value endpoint does not gate on
|
|
68
|
+
// If-Match, and a bad group's 404 CustomPreferenceGroupNotFoundException
|
|
69
|
+
// is surfaced verbatim through formatOcapiWriteToolResult.
|
|
70
|
+
const result = await ocapiPatchDirect(path, body, credentials);
|
|
71
|
+
return formatOcapiWriteToolResult(result, "PATCH", path);
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return unexpectedEnvelope();
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
// Registration
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
81
|
+
/** Tool names registered by this module. */
|
|
82
|
+
export const SITE_PREFERENCE_WRITE_TOOL_NAMES = ["site_preference_values_set"];
|
|
83
|
+
/**
|
|
84
|
+
* Register the SFCC site-preference value write tool.
|
|
85
|
+
* Called from `registerSfccWriteTools` — no direct `index.ts` edits needed.
|
|
86
|
+
*/
|
|
87
|
+
export function registerSitePreferenceWriteTools(registerTool, deps) {
|
|
88
|
+
const { gateDeps } = deps;
|
|
89
|
+
registerTool("site_preference_values_set", {
|
|
90
|
+
description: "Set custom site-preference VALUES via PATCH /site_preferences/preference_groups/{group}/sandbox. " +
|
|
91
|
+
"Sandbox-only, destructive; body is a flat map of c_-prefixed ids to string/number/boolean/string[] " +
|
|
92
|
+
"values. A bad group returns 404 CustomPreferenceGroupNotFoundException; echoes grant JSON on 403.",
|
|
93
|
+
inputSchema: sitePreferenceValuesSetInput,
|
|
94
|
+
annotations: WRITE_ANNOTATIONS,
|
|
95
|
+
}, buildSitePreferenceValuesSetHandler(gateDeps));
|
|
96
|
+
}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure OCAPI payload builders for the SFCC system-object write tools (BAPI-583).
|
|
3
|
+
*
|
|
4
|
+
* This module contains ONLY request-body construction and shape validation for
|
|
5
|
+
* the system-object write surface (attribute definitions, attribute groups,
|
|
6
|
+
* attribute-to-group assignment, and custom preference definitions). It performs
|
|
7
|
+
* NO network calls and imports NO transport code — transport lives in
|
|
8
|
+
* `client.ts` (`ocapiPut`/`ocapiPatch`). Keeping the builders decoupled from
|
|
9
|
+
* transport lets the same `ObjectAttributeDefinition` body helper back both the
|
|
10
|
+
* system-object writes here and later custom-object writes without duplication.
|
|
11
|
+
*/
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// Shared field schemas
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
/** Localized OCAPI string: a map of locale key → string value (e.g. `{ default: "Color" }`). */
|
|
17
|
+
export const localizedStringSchema = z.record(z.string(), z.string());
|
|
18
|
+
/**
|
|
19
|
+
* OCAPI attribute value types recognized by the read surface (mirrors the set
|
|
20
|
+
* in `ocapi-shape.ts`/`reads-system-object.ts`). Note `html`/`image` are valid
|
|
21
|
+
* *value types* even though `html`/`image` are output-only *properties* — the
|
|
22
|
+
* two restrictions are independent (see the create-body superRefine below).
|
|
23
|
+
*/
|
|
24
|
+
export const objectAttributeValueTypeSchema = z.enum([
|
|
25
|
+
"string",
|
|
26
|
+
"int",
|
|
27
|
+
"double",
|
|
28
|
+
"text",
|
|
29
|
+
"html",
|
|
30
|
+
"date",
|
|
31
|
+
"image",
|
|
32
|
+
"boolean",
|
|
33
|
+
"money",
|
|
34
|
+
"quantity",
|
|
35
|
+
"datetime",
|
|
36
|
+
"email",
|
|
37
|
+
"password",
|
|
38
|
+
"set_of_string",
|
|
39
|
+
"set_of_int",
|
|
40
|
+
"set_of_double",
|
|
41
|
+
"enum_of_string",
|
|
42
|
+
"enum_of_int",
|
|
43
|
+
]);
|
|
44
|
+
/** OCAPI output-only response properties that must never appear in a write body. */
|
|
45
|
+
const OUTPUT_ONLY_BODY_PROPERTIES = ["html", "image"];
|
|
46
|
+
/**
|
|
47
|
+
* Flag any output-only property (`html`/`image`) present as a request-body key.
|
|
48
|
+
* Attached to both the create and patch body schemas so a caller cannot smuggle
|
|
49
|
+
* a server-computed field into a write.
|
|
50
|
+
*/
|
|
51
|
+
function rejectOutputOnlyProperties(body, ctx) {
|
|
52
|
+
for (const key of OUTPUT_ONLY_BODY_PROPERTIES) {
|
|
53
|
+
if (Object.prototype.hasOwnProperty.call(body, key)) {
|
|
54
|
+
ctx.addIssue({
|
|
55
|
+
code: z.ZodIssueCode.custom,
|
|
56
|
+
path: [key],
|
|
57
|
+
message: `'${key}' is an output-only OCAPI property and cannot be set on a write body. ` +
|
|
58
|
+
`(Use value_type: "${key}" to declare an ${key} attribute instead.)`,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// ---------------------------------------------------------------------------
|
|
64
|
+
// ObjectAttributeDefinition bodies
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
/**
|
|
67
|
+
* A curated subset of common OCAPI `ObjectAttributeDefinition` metadata fields.
|
|
68
|
+
* Kept intentionally small to bound the generated JSON-schema token cost;
|
|
69
|
+
* `.passthrough()` on the schemas below still preserves any other caller-provided
|
|
70
|
+
* OCAPI field (bounds, length, regexp, enum value_definitions, etc.) verbatim.
|
|
71
|
+
*/
|
|
72
|
+
const objectAttributeDefinitionCommonShape = {
|
|
73
|
+
id: z.string().optional(),
|
|
74
|
+
system: z.boolean().optional(),
|
|
75
|
+
display_name: localizedStringSchema.optional(),
|
|
76
|
+
description: localizedStringSchema.optional(),
|
|
77
|
+
mandatory: z.boolean().optional(),
|
|
78
|
+
localizable: z.boolean().optional(),
|
|
79
|
+
site_specific: z.boolean().optional(),
|
|
80
|
+
default_value: z.any().optional(),
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Create body for `PUT .../attribute_definitions/{id}`. `value_type` is required;
|
|
84
|
+
* every other field is optional. Additional OCAPI fields pass through untouched.
|
|
85
|
+
*/
|
|
86
|
+
export const objectAttributeDefinitionCreateBodySchema = z
|
|
87
|
+
.object({
|
|
88
|
+
value_type: objectAttributeValueTypeSchema.describe("Required OCAPI attribute value type."),
|
|
89
|
+
...objectAttributeDefinitionCommonShape,
|
|
90
|
+
})
|
|
91
|
+
.passthrough()
|
|
92
|
+
.superRefine(rejectOutputOnlyProperties);
|
|
93
|
+
/**
|
|
94
|
+
* Patch body for `PATCH .../attribute_definitions/{id}`. Every field is optional
|
|
95
|
+
* (`value_type` included), but an empty patch is rejected and the same
|
|
96
|
+
* output-only property restriction applies.
|
|
97
|
+
*/
|
|
98
|
+
export const objectAttributeDefinitionPatchBodySchema = z
|
|
99
|
+
.object({
|
|
100
|
+
value_type: objectAttributeValueTypeSchema.optional(),
|
|
101
|
+
...objectAttributeDefinitionCommonShape,
|
|
102
|
+
})
|
|
103
|
+
.passthrough()
|
|
104
|
+
.superRefine((body, ctx) => {
|
|
105
|
+
rejectOutputOnlyProperties(body, ctx);
|
|
106
|
+
if (Object.keys(body).length === 0) {
|
|
107
|
+
ctx.addIssue({
|
|
108
|
+
code: z.ZodIssueCode.custom,
|
|
109
|
+
message: "Patch body must contain at least one field to update.",
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
// Attribute-group bodies
|
|
115
|
+
// ---------------------------------------------------------------------------
|
|
116
|
+
/** Create body for `PUT .../attribute_groups/{id}` — localized `display_name` + `internal`. */
|
|
117
|
+
export const attributeGroupPutBodySchema = z.object({
|
|
118
|
+
display_name: localizedStringSchema.describe("Localized group display name."),
|
|
119
|
+
internal: z.boolean().describe("Whether the group is internal (BM-only)."),
|
|
120
|
+
});
|
|
121
|
+
/** Patch body for `PATCH .../attribute_groups/{id}` — both fields optional, no empty patch. */
|
|
122
|
+
export const attributeGroupPatchBodySchema = z
|
|
123
|
+
.object({
|
|
124
|
+
display_name: localizedStringSchema.optional(),
|
|
125
|
+
internal: z.boolean().optional(),
|
|
126
|
+
})
|
|
127
|
+
.superRefine((body, ctx) => {
|
|
128
|
+
if (Object.keys(body).length === 0) {
|
|
129
|
+
ctx.addIssue({
|
|
130
|
+
code: z.ZodIssueCode.custom,
|
|
131
|
+
message: "Patch body must contain at least one field to update.",
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
// ---------------------------------------------------------------------------
|
|
136
|
+
// Local payload faults (mirror OCAPI fault shape for pre-transport rejections)
|
|
137
|
+
// ---------------------------------------------------------------------------
|
|
138
|
+
/**
|
|
139
|
+
* A local, pre-transport payload-shape failure that should surface to callers in
|
|
140
|
+
* the same OCAPI-fault vocabulary the server would use (e.g. `IdConflictException`).
|
|
141
|
+
* Carries an HTTP `status` and an OCAPI-style `faultType` so the handler can build
|
|
142
|
+
* a fault envelope without a network round-trip.
|
|
143
|
+
*/
|
|
144
|
+
export class SfccWritePayloadFault extends Error {
|
|
145
|
+
status;
|
|
146
|
+
faultType;
|
|
147
|
+
constructor(faultType, message, status = 400) {
|
|
148
|
+
super(message);
|
|
149
|
+
this.name = "SfccWritePayloadFault";
|
|
150
|
+
this.faultType = faultType;
|
|
151
|
+
this.status = status;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// ---------------------------------------------------------------------------
|
|
155
|
+
// Attribute-definition payload builders
|
|
156
|
+
// ---------------------------------------------------------------------------
|
|
157
|
+
/**
|
|
158
|
+
* Build the create payload for `PUT .../attribute_definitions/{urlId}`.
|
|
159
|
+
*
|
|
160
|
+
* Enforces the two write-time invariants the ticket requires BEFORE any transport:
|
|
161
|
+
* - a supplied `id` must equal the URL id (else `IdConflictException`);
|
|
162
|
+
* - `system` must not be `true` (else `AttributeDefinitionKeyReadOnlyException`).
|
|
163
|
+
* Returns a new object with `id` forced to the URL id and `system` forced to
|
|
164
|
+
* `false`, preserving every other caller-provided OCAPI field verbatim.
|
|
165
|
+
*/
|
|
166
|
+
export function buildObjectAttributeDefinitionCreatePayload(urlId, body) {
|
|
167
|
+
if (body.id !== undefined && body.id !== urlId) {
|
|
168
|
+
throw new SfccWritePayloadFault("IdConflictException", `Attribute definition id '${body.id}' does not match the URL id '${urlId}'. ` +
|
|
169
|
+
`Omit 'id' or set it equal to the URL id.`);
|
|
170
|
+
}
|
|
171
|
+
if (body.system === true) {
|
|
172
|
+
throw new SfccWritePayloadFault("AttributeDefinitionKeyReadOnlyException", "Cannot create a system attribute definition (system: true) over OCAPI writes.");
|
|
173
|
+
}
|
|
174
|
+
return { ...body, id: urlId, system: false };
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Build the patch payload for `PATCH .../attribute_definitions/{urlId}`.
|
|
178
|
+
*
|
|
179
|
+
* Applies the same id-match and non-system guards as the create builder, then
|
|
180
|
+
* returns the caller's patch fields unchanged — it invents no transport fields
|
|
181
|
+
* and does not force `id`/`system` onto a partial update.
|
|
182
|
+
*/
|
|
183
|
+
export function buildObjectAttributeDefinitionPatchPayload(urlId, body) {
|
|
184
|
+
if (body.id !== undefined && body.id !== urlId) {
|
|
185
|
+
throw new SfccWritePayloadFault("IdConflictException", `Attribute definition id '${body.id}' does not match the URL id '${urlId}'. ` +
|
|
186
|
+
`Omit 'id' or set it equal to the URL id.`);
|
|
187
|
+
}
|
|
188
|
+
if (body.system === true) {
|
|
189
|
+
throw new SfccWritePayloadFault("AttributeDefinitionKeyReadOnlyException", "Cannot patch an attribute definition to system: true over OCAPI writes.");
|
|
190
|
+
}
|
|
191
|
+
return { ...body };
|
|
192
|
+
}
|
|
193
|
+
// ---------------------------------------------------------------------------
|
|
194
|
+
// Attribute-group payload builders
|
|
195
|
+
// ---------------------------------------------------------------------------
|
|
196
|
+
/** Build the minimal create body for an attribute group: exactly `{ display_name, internal }`. */
|
|
197
|
+
export function buildAttributeGroupPutPayload(body) {
|
|
198
|
+
return { display_name: body.display_name, internal: body.internal };
|
|
199
|
+
}
|
|
200
|
+
/** Build the attribute-group patch body from only the supplied fields. */
|
|
201
|
+
export function buildAttributeGroupPatchPayload(body) {
|
|
202
|
+
return { ...body };
|
|
203
|
+
}
|
|
204
|
+
// ---------------------------------------------------------------------------
|
|
205
|
+
// Relation payload builder
|
|
206
|
+
// ---------------------------------------------------------------------------
|
|
207
|
+
/**
|
|
208
|
+
* Build the (empty) body for the attribute→group assignment PUT. The relation is
|
|
209
|
+
* fully expressed by the URL, so OCAPI expects an empty JSON object body.
|
|
210
|
+
*/
|
|
211
|
+
export function buildEmptyRelationPayload() {
|
|
212
|
+
return {};
|
|
213
|
+
}
|