@vendure/dashboard 3.3.6-master-202507010731 → 3.3.6-master-202507010922

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vendure/dashboard",
3
3
  "private": false,
4
- "version": "3.3.6-master-202507010731",
4
+ "version": "3.3.6-master-202507010922",
5
5
  "type": "module",
6
6
  "repository": {
7
7
  "type": "git",
@@ -86,8 +86,8 @@
86
86
  "@types/react-dom": "^19.0.4",
87
87
  "@types/react-grid-layout": "^1.3.5",
88
88
  "@uidotdev/usehooks": "^2.4.1",
89
- "@vendure/common": "^3.3.6-master-202507010731",
90
- "@vendure/core": "^3.3.6-master-202507010731",
89
+ "@vendure/common": "^3.3.6-master-202507010922",
90
+ "@vendure/core": "^3.3.6-master-202507010922",
91
91
  "@vitejs/plugin-react": "^4.3.4",
92
92
  "awesome-graphql-client": "^2.1.0",
93
93
  "class-variance-authority": "^0.7.1",
@@ -130,5 +130,5 @@
130
130
  "lightningcss-linux-arm64-musl": "^1.29.3",
131
131
  "lightningcss-linux-x64-musl": "^1.29.1"
132
132
  },
133
- "gitHead": "f5da386affaa5dcc54296a51228e2a7e5d3b0f84"
133
+ "gitHead": "ea754102804748c447cf9c1d28d9bbc5cc0a333b"
134
134
  }
@@ -0,0 +1,134 @@
1
+ import { useMutation } from '@tanstack/react-query';
2
+ import { CopyIcon } from 'lucide-react';
3
+ import { useState } from 'react';
4
+ import { toast } from 'sonner';
5
+
6
+ import { DataTableBulkActionItem } from '@/components/data-table/data-table-bulk-action-item.js';
7
+ import { api } from '@/graphql/api.js';
8
+ import { duplicateEntityDocument } from '@/graphql/common-operations.js';
9
+ import { usePaginatedList } from '@/index.js';
10
+ import { Trans, useLingui } from '@/lib/trans.js';
11
+
12
+ interface DuplicateBulkActionProps {
13
+ entityType: 'Product' | 'Collection';
14
+ duplicatorCode: string;
15
+ duplicatorArguments?: Array<{ name: string; value: string }>;
16
+ requiredPermissions: string[];
17
+ entityName: string; // For display purposes in error messages
18
+ onSuccess?: () => void;
19
+ selection: any[];
20
+ table: any;
21
+ }
22
+
23
+ export function DuplicateBulkAction({
24
+ entityType,
25
+ duplicatorCode,
26
+ duplicatorArguments = [],
27
+ requiredPermissions,
28
+ entityName,
29
+ onSuccess,
30
+ selection,
31
+ table,
32
+ }: DuplicateBulkActionProps) {
33
+ const { refetchPaginatedList } = usePaginatedList();
34
+ const { i18n } = useLingui();
35
+ const [isDuplicating, setIsDuplicating] = useState(false);
36
+ const [progress, setProgress] = useState({ completed: 0, total: 0 });
37
+
38
+ const { mutateAsync } = useMutation({
39
+ mutationFn: api.mutate(duplicateEntityDocument),
40
+ });
41
+
42
+ const handleDuplicate = async () => {
43
+ if (isDuplicating) return;
44
+
45
+ setIsDuplicating(true);
46
+ setProgress({ completed: 0, total: selection.length });
47
+
48
+ const results = {
49
+ success: 0,
50
+ failed: 0,
51
+ errors: [] as string[],
52
+ };
53
+
54
+ try {
55
+ // Process entities sequentially to avoid overwhelming the server
56
+ for (let i = 0; i < selection.length; i++) {
57
+ const entity = selection[i];
58
+
59
+ try {
60
+ const result = await mutateAsync({
61
+ input: {
62
+ entityName: entityType,
63
+ entityId: entity.id,
64
+ duplicatorInput: {
65
+ code: duplicatorCode,
66
+ arguments: duplicatorArguments,
67
+ },
68
+ },
69
+ });
70
+
71
+ if ('newEntityId' in result.duplicateEntity) {
72
+ results.success++;
73
+ } else {
74
+ results.failed++;
75
+ const errorMsg =
76
+ result.duplicateEntity.message ||
77
+ result.duplicateEntity.duplicationError ||
78
+ 'Unknown error';
79
+ results.errors.push(`${entityName} ${entity.name || entity.id}: ${errorMsg}`);
80
+ }
81
+ } catch (error) {
82
+ results.failed++;
83
+ results.errors.push(
84
+ `${entityName} ${entity.name || entity.id}: ${error instanceof Error ? error.message : 'Unknown error'}`,
85
+ );
86
+ }
87
+
88
+ setProgress({ completed: i + 1, total: selection.length });
89
+ }
90
+
91
+ // Show results
92
+ if (results.success > 0) {
93
+ toast.success(
94
+ i18n.t(`Successfully duplicated ${results.success} ${entityName.toLowerCase()}s`),
95
+ );
96
+ }
97
+ if (results.failed > 0) {
98
+ const errorMessage =
99
+ results.errors.length > 3
100
+ ? `${results.errors.slice(0, 3).join(', ')}... and ${results.errors.length - 3} more`
101
+ : results.errors.join(', ');
102
+ toast.error(
103
+ `Failed to duplicate ${results.failed} ${entityName.toLowerCase()}s: ${errorMessage}`,
104
+ );
105
+ }
106
+
107
+ if (results.success > 0) {
108
+ refetchPaginatedList();
109
+ table.resetRowSelection();
110
+ onSuccess?.();
111
+ }
112
+ } finally {
113
+ setIsDuplicating(false);
114
+ setProgress({ completed: 0, total: 0 });
115
+ }
116
+ };
117
+
118
+ return (
119
+ <DataTableBulkActionItem
120
+ requiresPermission={requiredPermissions}
121
+ onClick={handleDuplicate}
122
+ label={
123
+ isDuplicating ? (
124
+ <Trans>
125
+ Duplicating... ({progress.completed}/{progress.total})
126
+ </Trans>
127
+ ) : (
128
+ <Trans>Duplicate</Trans>
129
+ )
130
+ }
131
+ icon={CopyIcon}
132
+ />
133
+ );
134
+ }
@@ -147,3 +147,12 @@ export const removeCollectionFromChannelDocument = graphql(`
147
147
  }
148
148
  }
149
149
  `);
150
+
151
+ export const deleteCollectionsDocument = graphql(`
152
+ mutation DeleteCollections($ids: [ID!]!) {
153
+ deleteCollections(ids: $ids) {
154
+ result
155
+ message
156
+ }
157
+ }
158
+ `);
@@ -16,6 +16,8 @@ import { useState } from 'react';
16
16
  import { collectionListDocument, deleteCollectionDocument } from './collections.graphql.js';
17
17
  import {
18
18
  AssignCollectionsToChannelBulkAction,
19
+ DeleteCollectionsBulkAction,
20
+ DuplicateCollectionsBulkAction,
19
21
  RemoveCollectionsFromChannelBulkAction,
20
22
  } from './components/collection-bulk-actions.js';
21
23
  import { CollectionContentsSheet } from './components/collection-contents-sheet.js';
@@ -192,6 +194,14 @@ function CollectionListPage() {
192
194
  component: RemoveCollectionsFromChannelBulkAction,
193
195
  order: 200,
194
196
  },
197
+ {
198
+ component: DuplicateCollectionsBulkAction,
199
+ order: 300,
200
+ },
201
+ {
202
+ component: DeleteCollectionsBulkAction,
203
+ order: 400,
204
+ },
195
205
  ]}
196
206
  >
197
207
  <PageActionBarRight>
@@ -1,17 +1,17 @@
1
1
  import { useMutation, useQueryClient } from '@tanstack/react-query';
2
- import { LayersIcon } from 'lucide-react';
2
+ import { LayersIcon, TrashIcon } from 'lucide-react';
3
3
  import { useState } from 'react';
4
4
  import { toast } from 'sonner';
5
5
 
6
6
  import { DataTableBulkActionItem } from '@/components/data-table/data-table-bulk-action-item.js';
7
7
  import { BulkActionComponent } from '@/framework/data-table/data-table-types.js';
8
8
  import { api } from '@/graphql/api.js';
9
- import { useChannel, usePaginatedList } from '@/index.js';
9
+ import { ResultOf, useChannel, usePaginatedList } from '@/index.js';
10
10
  import { Trans, useLingui } from '@/lib/trans.js';
11
-
12
- import { Permission } from '@vendure/common/lib/generated-types';
11
+ import { DuplicateBulkAction } from '../../../../common/duplicate-bulk-action.js';
13
12
  import {
14
13
  assignCollectionToChannelDocument,
14
+ deleteCollectionsDocument,
15
15
  removeCollectionFromChannelDocument,
16
16
  } from '../collections.graphql.js';
17
17
  import { AssignCollectionsToChannelDialog } from './assign-collections-to-channel-dialog.js';
@@ -35,7 +35,7 @@ export const AssignCollectionsToChannelBulkAction: BulkActionComponent<any> = ({
35
35
  return (
36
36
  <>
37
37
  <DataTableBulkActionItem
38
- requiresPermission={[Permission.UpdateCatalog, Permission.UpdateCollection]}
38
+ requiresPermission={['UpdateCatalog', 'UpdateCollection']}
39
39
  onClick={() => setDialogOpen(true)}
40
40
  label={<Trans>Assign to channel</Trans>}
41
41
  icon={LayersIcon}
@@ -84,7 +84,7 @@ export const RemoveCollectionsFromChannelBulkAction: BulkActionComponent<any> =
84
84
 
85
85
  return (
86
86
  <DataTableBulkActionItem
87
- requiresPermission={[Permission.UpdateCatalog, Permission.UpdateCollection]}
87
+ requiresPermission={['UpdateCatalog', 'UpdateCollection']}
88
88
  onClick={handleRemove}
89
89
  label={<Trans>Remove from current channel</Trans>}
90
90
  confirmationText={
@@ -97,3 +97,63 @@ export const RemoveCollectionsFromChannelBulkAction: BulkActionComponent<any> =
97
97
  />
98
98
  );
99
99
  };
100
+
101
+ export const DuplicateCollectionsBulkAction: BulkActionComponent<any> = ({ selection, table }) => {
102
+ const queryClient = useQueryClient();
103
+ return (
104
+ <DuplicateBulkAction
105
+ entityType="Collection"
106
+ duplicatorCode="collection-duplicator"
107
+ duplicatorArguments={[]}
108
+ requiredPermissions={['UpdateCatalog', 'UpdateCollection']}
109
+ entityName="Collection"
110
+ selection={selection}
111
+ table={table}
112
+ onSuccess={() => {
113
+ queryClient.invalidateQueries({ queryKey: ['childCollections'] });
114
+ }}
115
+ />
116
+ );
117
+ };
118
+
119
+ export const DeleteCollectionsBulkAction: BulkActionComponent<any> = ({ selection, table }) => {
120
+ const { refetchPaginatedList } = usePaginatedList();
121
+ const { i18n } = useLingui();
122
+ const queryClient = useQueryClient();
123
+ const { mutate } = useMutation({
124
+ mutationFn: api.mutate(deleteCollectionsDocument),
125
+ onSuccess: (result: ResultOf<typeof deleteCollectionsDocument>) => {
126
+ let deleted = 0;
127
+ const errors: string[] = [];
128
+ for (const item of result.deleteCollections) {
129
+ if (item.result === 'DELETED') {
130
+ deleted++;
131
+ } else if (item.message) {
132
+ errors.push(item.message);
133
+ }
134
+ }
135
+ if (0 < deleted) {
136
+ toast.success(i18n.t(`Deleted ${deleted} collections`));
137
+ }
138
+ if (0 < errors.length) {
139
+ toast.error(i18n.t(`Failed to delete ${errors.length} collections`));
140
+ }
141
+ refetchPaginatedList();
142
+ table.resetRowSelection();
143
+ queryClient.invalidateQueries({ queryKey: ['childCollections'] });
144
+ },
145
+ onError: () => {
146
+ toast.error(`Failed to delete ${selection.length} collections`);
147
+ },
148
+ });
149
+ return (
150
+ <DataTableBulkActionItem
151
+ requiresPermission={['DeleteCatalog', 'DeleteCollection']}
152
+ onClick={() => mutate({ ids: selection.map(s => s.id) })}
153
+ label={<Trans>Delete</Trans>}
154
+ confirmationText={<Trans>Are you sure you want to delete {selection.length} collections?</Trans>}
155
+ icon={TrashIcon}
156
+ className="text-destructive"
157
+ />
158
+ );
159
+ };
@@ -10,7 +10,6 @@ import { ResultOf } from '@/graphql/graphql.js';
10
10
  import { useChannel, usePaginatedList } from '@/index.js';
11
11
  import { Trans, useLingui } from '@/lib/trans.js';
12
12
 
13
- import { Permission } from '@vendure/common/lib/generated-types';
14
13
  import { AssignFacetValuesDialog } from '../../_products/components/assign-facet-values-dialog.js';
15
14
  import { AssignToChannelDialog } from '../../_products/components/assign-to-channel-dialog.js';
16
15
  import {
@@ -52,7 +51,7 @@ export const DeleteProductVariantsBulkAction: BulkActionComponent<any> = ({ sele
52
51
  });
53
52
  return (
54
53
  <DataTableBulkActionItem
55
- requiresPermission={[Permission.DeleteCatalog, Permission.DeleteProduct]}
54
+ requiresPermission={['DeleteCatalog', 'DeleteProduct']}
56
55
  onClick={() => mutate({ ids: selection.map(s => s.id) })}
57
56
  label={<Trans>Delete</Trans>}
58
57
  confirmationText={
@@ -81,7 +80,7 @@ export const AssignProductVariantsToChannelBulkAction: BulkActionComponent<any>
81
80
  return (
82
81
  <>
83
82
  <DataTableBulkActionItem
84
- requiresPermission={[Permission.UpdateCatalog, Permission.UpdateProduct]}
83
+ requiresPermission={['UpdateCatalog', 'UpdateProduct']}
85
84
  onClick={() => setDialogOpen(true)}
86
85
  label={<Trans>Assign to channel</Trans>}
87
86
  icon={LayersIcon}
@@ -134,7 +133,7 @@ export const RemoveProductVariantsFromChannelBulkAction: BulkActionComponent<any
134
133
 
135
134
  return (
136
135
  <DataTableBulkActionItem
137
- requiresPermission={[Permission.UpdateCatalog, Permission.UpdateProduct]}
136
+ requiresPermission={['UpdateCatalog', 'UpdateProduct']}
138
137
  onClick={handleRemove}
139
138
  label={<Trans>Remove from current channel</Trans>}
140
139
  confirmationText={
@@ -164,7 +163,7 @@ export const AssignFacetValuesToProductVariantsBulkAction: BulkActionComponent<a
164
163
  return (
165
164
  <>
166
165
  <DataTableBulkActionItem
167
- requiresPermission={[Permission.UpdateCatalog, Permission.UpdateProduct]}
166
+ requiresPermission={['UpdateCatalog', 'UpdateProduct']}
168
167
  onClick={() => setDialogOpen(true)}
169
168
  label={<Trans>Edit facet values</Trans>}
170
169
  icon={TagIcon}
@@ -1,5 +1,5 @@
1
1
  import { useMutation } from '@tanstack/react-query';
2
- import { CopyIcon, LayersIcon, TagIcon, TrashIcon } from 'lucide-react';
2
+ import { LayersIcon, TagIcon, TrashIcon } from 'lucide-react';
3
3
  import { useState } from 'react';
4
4
  import { toast } from 'sonner';
5
5
 
@@ -9,12 +9,10 @@ import { api } from '@/graphql/api.js';
9
9
  import { ResultOf } from '@/graphql/graphql.js';
10
10
  import { useChannel, usePaginatedList } from '@/index.js';
11
11
  import { Trans, useLingui } from '@/lib/trans.js';
12
-
13
- import { Permission } from '@vendure/common/lib/generated-types';
12
+ import { DuplicateBulkAction } from '../../../../common/duplicate-bulk-action.js';
14
13
  import {
15
14
  assignProductsToChannelDocument,
16
15
  deleteProductsDocument,
17
- duplicateEntityDocument,
18
16
  getProductsWithFacetValuesByIdsDocument,
19
17
  productDetailDocument,
20
18
  removeProductsFromChannelDocument,
@@ -53,7 +51,7 @@ export const DeleteProductsBulkAction: BulkActionComponent<any> = ({ selection,
53
51
  });
54
52
  return (
55
53
  <DataTableBulkActionItem
56
- requiresPermission={[Permission.DeleteCatalog, Permission.DeleteProduct]}
54
+ requiresPermission={['DeleteCatalog', 'DeleteProduct']}
57
55
  onClick={() => mutate({ ids: selection.map(s => s.id) })}
58
56
  label={<Trans>Delete</Trans>}
59
57
  confirmationText={<Trans>Are you sure you want to delete {selection.length} products?</Trans>}
@@ -80,7 +78,7 @@ export const AssignProductsToChannelBulkAction: BulkActionComponent<any> = ({ se
80
78
  return (
81
79
  <>
82
80
  <DataTableBulkActionItem
83
- requiresPermission={[Permission.UpdateCatalog, Permission.UpdateProduct]}
81
+ requiresPermission={['UpdateCatalog', 'UpdateProduct']}
84
82
  onClick={() => setDialogOpen(true)}
85
83
  label={<Trans>Assign to channel</Trans>}
86
84
  icon={LayersIcon}
@@ -128,7 +126,7 @@ export const RemoveProductsFromChannelBulkAction: BulkActionComponent<any> = ({
128
126
 
129
127
  return (
130
128
  <DataTableBulkActionItem
131
- requiresPermission={[Permission.UpdateCatalog, Permission.UpdateProduct]}
129
+ requiresPermission={['UpdateCatalog', 'UpdateProduct']}
132
130
  onClick={handleRemove}
133
131
  label={<Trans>Remove from current channel</Trans>}
134
132
  confirmationText={
@@ -154,7 +152,7 @@ export const AssignFacetValuesToProductsBulkAction: BulkActionComponent<any> = (
154
152
  return (
155
153
  <>
156
154
  <DataTableBulkActionItem
157
- requiresPermission={[Permission.UpdateCatalog, Permission.UpdateProduct]}
155
+ requiresPermission={['UpdateCatalog', 'UpdateProduct']}
158
156
  onClick={() => setDialogOpen(true)}
159
157
  label={<Trans>Edit facet values</Trans>}
160
158
  icon={TagIcon}
@@ -174,105 +172,20 @@ export const AssignFacetValuesToProductsBulkAction: BulkActionComponent<any> = (
174
172
  };
175
173
 
176
174
  export const DuplicateProductsBulkAction: BulkActionComponent<any> = ({ selection, table }) => {
177
- const { refetchPaginatedList } = usePaginatedList();
178
- const { i18n } = useLingui();
179
- const [isDuplicating, setIsDuplicating] = useState(false);
180
- const [progress, setProgress] = useState({ completed: 0, total: 0 });
181
-
182
- const { mutateAsync } = useMutation({
183
- mutationFn: api.mutate(duplicateEntityDocument),
184
- });
185
-
186
- const handleDuplicate = async () => {
187
- if (isDuplicating) return;
188
-
189
- setIsDuplicating(true);
190
- setProgress({ completed: 0, total: selection.length });
191
-
192
- const results = {
193
- success: 0,
194
- failed: 0,
195
- errors: [] as string[],
196
- };
197
-
198
- try {
199
- // Process products sequentially to avoid overwhelming the server
200
- for (let i = 0; i < selection.length; i++) {
201
- const product = selection[i];
202
-
203
- try {
204
- const result = await mutateAsync({
205
- input: {
206
- entityName: 'Product',
207
- entityId: product.id,
208
- duplicatorInput: {
209
- code: 'product-duplicator',
210
- arguments: [
211
- {
212
- name: 'includeVariants',
213
- value: 'true',
214
- },
215
- ],
216
- },
217
- },
218
- });
219
-
220
- if ('newEntityId' in result.duplicateEntity) {
221
- results.success++;
222
- } else {
223
- results.failed++;
224
- const errorMsg =
225
- result.duplicateEntity.message ||
226
- result.duplicateEntity.duplicationError ||
227
- 'Unknown error';
228
- results.errors.push(`Product ${product.name || product.id}: ${errorMsg}`);
229
- }
230
- } catch (error) {
231
- results.failed++;
232
- results.errors.push(
233
- `Product ${product.name || product.id}: ${error instanceof Error ? error.message : 'Unknown error'}`,
234
- );
235
- }
236
-
237
- setProgress({ completed: i + 1, total: selection.length });
238
- }
239
-
240
- // Show results
241
- if (results.success > 0) {
242
- toast.success(i18n.t(`Successfully duplicated ${results.success} products`));
243
- }
244
- if (results.failed > 0) {
245
- const errorMessage =
246
- results.errors.length > 3
247
- ? `${results.errors.slice(0, 3).join(', ')}... and ${results.errors.length - 3} more`
248
- : results.errors.join(', ');
249
- toast.error(`Failed to duplicate ${results.failed} products: ${errorMessage}`);
250
- }
251
-
252
- if (results.success > 0) {
253
- refetchPaginatedList();
254
- table.resetRowSelection();
255
- }
256
- } finally {
257
- setIsDuplicating(false);
258
- setProgress({ completed: 0, total: 0 });
259
- }
260
- };
261
-
262
175
  return (
263
- <DataTableBulkActionItem
264
- requiresPermission={[Permission.UpdateCatalog, Permission.UpdateProduct]}
265
- onClick={handleDuplicate}
266
- label={
267
- isDuplicating ? (
268
- <Trans>
269
- Duplicating... ({progress.completed}/{progress.total})
270
- </Trans>
271
- ) : (
272
- <Trans>Duplicate</Trans>
273
- )
274
- }
275
- icon={CopyIcon}
176
+ <DuplicateBulkAction
177
+ entityType="Product"
178
+ duplicatorCode="product-duplicator"
179
+ duplicatorArguments={[
180
+ {
181
+ name: 'includeVariants',
182
+ value: 'true',
183
+ },
184
+ ]}
185
+ requiredPermissions={['UpdateCatalog', 'UpdateProduct']}
186
+ entityName="Product"
187
+ selection={selection}
188
+ table={table}
276
189
  />
277
190
  );
278
191
  };
@@ -187,20 +187,3 @@ export const getProductsWithFacetValuesByIdsDocument = graphql(`
187
187
  }
188
188
  }
189
189
  `);
190
-
191
- export const duplicateEntityDocument = graphql(`
192
- mutation DuplicateEntity($input: DuplicateEntityInput!) {
193
- duplicateEntity(input: $input) {
194
- ... on DuplicateEntitySuccess {
195
- newEntityId
196
- }
197
- ... on ErrorResult {
198
- errorCode
199
- message
200
- }
201
- ... on DuplicateEntityError {
202
- duplicationError
203
- }
204
- }
205
- }
206
- `);
@@ -41,7 +41,12 @@ export function CustomFieldsForm({ entityType, control, formPathPrefix }: Custom
41
41
  const customFields = useCustomFieldConfig(entityType);
42
42
 
43
43
  const getFieldName = (fieldDef: CustomFieldConfig) => {
44
- const name = fieldDef.type === 'relation' ? fieldDef.name + 'Id' : fieldDef.name;
44
+ const name =
45
+ fieldDef.type === 'relation'
46
+ ? fieldDef.list
47
+ ? fieldDef.name + 'Ids'
48
+ : fieldDef.name + 'Id'
49
+ : fieldDef.name;
45
50
  return formPathPrefix ? `${formPathPrefix}.customFields.${name}` : `customFields.${name}`;
46
51
  };
47
52
 
@@ -266,6 +271,18 @@ function FormInputForType({
266
271
  );
267
272
  case 'boolean':
268
273
  return <Switch checked={field.value} onCheckedChange={field.onChange} disabled={isReadonly} />;
274
+ case 'relation':
275
+ if (fieldDef.list) {
276
+ return (
277
+ <Input
278
+ {...field}
279
+ onChange={e => field.onChange(e.target.value.split(','))}
280
+ disabled={isReadonly}
281
+ />
282
+ );
283
+ } else {
284
+ return <Input {...field} disabled={isReadonly} />;
285
+ }
269
286
  default:
270
287
  return <Input {...field} disabled={isReadonly} />;
271
288
  }
@@ -1,24 +1,52 @@
1
1
  import { FieldInfo } from '../document-introspection/get-document-structure.js';
2
2
 
3
- export function transformRelationFields<E extends Record<string, any>>(fields: FieldInfo[], entity: E) {
4
- const processedEntity = { ...entity } as any;
3
+ /**
4
+ * Transforms relation fields in an entity, extracting IDs from relation objects.
5
+ * This is primarily used for custom fields of type "ID".
6
+ *
7
+ * @param fields - Array of field information
8
+ * @param entity - The entity to transform
9
+ * @returns A new entity with transformed relation fields
10
+ */
11
+ export function transformRelationFields<E extends Record<string, any>>(fields: FieldInfo[], entity: E): E {
12
+ // Create a shallow copy to avoid mutating the original entity
13
+ const processedEntity = { ...entity };
5
14
 
6
- for (const field of fields) {
7
- if (field.name !== 'customFields' || !field.typeInfo) {
8
- continue;
9
- }
15
+ // Skip processing if there are no custom fields
16
+ if (!entity.customFields || !processedEntity.customFields) {
17
+ return processedEntity;
18
+ }
10
19
 
11
- if (!entity.customFields || !processedEntity.customFields) {
12
- continue;
13
- }
20
+ // Find the customFields field info
21
+ const customFieldsInfo = fields.find(field => field.name === 'customFields' && field.typeInfo);
22
+ if (!customFieldsInfo?.typeInfo) {
23
+ return processedEntity;
24
+ }
25
+
26
+ // Process only ID type custom fields
27
+ const idTypeCustomFields = customFieldsInfo.typeInfo.filter(field => field.type === 'ID');
14
28
 
15
- for (const customField of field.typeInfo) {
16
- if (customField.type === 'ID') {
17
- const relationField = customField.name;
18
- const propertyAccessorKey = customField.name.replace(/Id$/, '');
19
- const relationValue = entity.customFields[propertyAccessorKey];
20
- const relationIdValue = relationValue?.id;
29
+ for (const customField of idTypeCustomFields) {
30
+ const relationField = customField.name;
31
+
32
+ if (customField.list) {
33
+ // For list fields, the accessor is the field name without the "Ids" suffix
34
+ const propertyAccessorKey = customField.name.replace(/Ids$/, '');
35
+ const relationValue = entity.customFields[propertyAccessorKey];
36
+
37
+ if (relationValue) {
38
+ const relationIdValue = relationValue.map((v: { id: string }) => v.id);
39
+ if (relationIdValue && relationIdValue.length > 0) {
40
+ processedEntity.customFields[relationField] = relationIdValue;
41
+ }
42
+ }
43
+ } else {
44
+ // For single fields, the accessor is the field name without the "Id" suffix
45
+ const propertyAccessorKey = customField.name.replace(/Id$/, '');
46
+ const relationValue = entity.customFields[propertyAccessorKey];
21
47
 
48
+ if (relationValue) {
49
+ const relationIdValue = relationValue.id;
22
50
  if (relationIdValue) {
23
51
  processedEntity.customFields[relationField] = relationIdValue;
24
52
  }
@@ -0,0 +1,18 @@
1
+ import { graphql } from './graphql.js';
2
+
3
+ export const duplicateEntityDocument = graphql(`
4
+ mutation DuplicateEntity($input: DuplicateEntityInput!) {
5
+ duplicateEntity(input: $input) {
6
+ ... on DuplicateEntitySuccess {
7
+ newEntityId
8
+ }
9
+ ... on ErrorResult {
10
+ errorCode
11
+ message
12
+ }
13
+ ... on DuplicateEntityError {
14
+ duplicationError
15
+ }
16
+ }
17
+ }
18
+ `);
@@ -1,4 +1,4 @@
1
- import { graphql, ResultOf } from "./graphql.js";
1
+ import { graphql, ResultOf } from './graphql.js';
2
2
 
3
3
  export const assetFragment = graphql(`
4
4
  fragment Asset on Asset {
@@ -58,5 +58,4 @@ export const errorResultFragment = graphql(`
58
58
  }
59
59
  `);
60
60
 
61
-
62
61
  export type ConfigurableOperationDefFragment = ResultOf<typeof configurableOperationDefFragment>;
@@ -100,7 +100,7 @@ export type introspection_types = {
100
100
  'CreateFulfillmentError': { kind: 'OBJECT'; name: 'CreateFulfillmentError'; fields: { 'errorCode': { name: 'errorCode'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'ENUM'; name: 'ErrorCode'; ofType: null; }; } }; 'fulfillmentHandlerError': { name: 'fulfillmentHandlerError'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'message': { name: 'message'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; }; };
101
101
  'CreateGroupOptionInput': { kind: 'INPUT_OBJECT'; name: 'CreateGroupOptionInput'; isOneOf: false; inputFields: [{ name: 'code'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; }; defaultValue: null }, { name: 'translations'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'ProductOptionGroupTranslationInput'; ofType: null; }; }; }; }; defaultValue: null }]; };
102
102
  'CreatePaymentMethodInput': { kind: 'INPUT_OBJECT'; name: 'CreatePaymentMethodInput'; isOneOf: false; inputFields: [{ name: 'code'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; }; defaultValue: null }, { name: 'enabled'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; }; defaultValue: null }, { name: 'checker'; type: { kind: 'INPUT_OBJECT'; name: 'ConfigurableOperationInput'; ofType: null; }; defaultValue: null }, { name: 'handler'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'ConfigurableOperationInput'; ofType: null; }; }; defaultValue: null }, { name: 'translations'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'PaymentMethodTranslationInput'; ofType: null; }; }; }; }; defaultValue: null }, { name: 'customFields'; type: { kind: 'SCALAR'; name: 'JSON'; ofType: null; }; defaultValue: null }]; };
103
- 'CreateProductCustomFieldsInput': { kind: 'INPUT_OBJECT'; name: 'CreateProductCustomFieldsInput'; isOneOf: false; inputFields: [{ name: 'infoUrl'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; }; defaultValue: null }, { name: 'downloadable'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; defaultValue: null }, { name: 'lastUpdated'; type: { kind: 'SCALAR'; name: 'DateTime'; ofType: null; }; defaultValue: null }, { name: 'reviewRating'; type: { kind: 'SCALAR'; name: 'Float'; ofType: null; }; defaultValue: null }, { name: 'reviewCount'; type: { kind: 'SCALAR'; name: 'Float'; ofType: null; }; defaultValue: null }, { name: 'featuredReviewId'; type: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; defaultValue: null }]; };
103
+ 'CreateProductCustomFieldsInput': { kind: 'INPUT_OBJECT'; name: 'CreateProductCustomFieldsInput'; isOneOf: false; inputFields: [{ name: 'infoUrl'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; }; defaultValue: null }, { name: 'downloadable'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; defaultValue: null }, { name: 'lastUpdated'; type: { kind: 'SCALAR'; name: 'DateTime'; ofType: null; }; defaultValue: null }, { name: 'reviewRating'; type: { kind: 'SCALAR'; name: 'Float'; ofType: null; }; defaultValue: null }, { name: 'reviewCount'; type: { kind: 'SCALAR'; name: 'Float'; ofType: null; }; defaultValue: null }, { name: 'featuredReviewId'; type: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; defaultValue: null }, { name: 'promotedReviewsIds'; type: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; }; }; defaultValue: null }]; };
104
104
  'CreateProductInput': { kind: 'INPUT_OBJECT'; name: 'CreateProductInput'; isOneOf: false; inputFields: [{ name: 'featuredAssetId'; type: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; defaultValue: null }, { name: 'enabled'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; defaultValue: null }, { name: 'assetIds'; type: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; }; }; defaultValue: null }, { name: 'facetValueIds'; type: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; }; }; defaultValue: null }, { name: 'translations'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'ProductTranslationInput'; ofType: null; }; }; }; }; defaultValue: null }, { name: 'customFields'; type: { kind: 'INPUT_OBJECT'; name: 'CreateProductCustomFieldsInput'; ofType: null; }; defaultValue: null }]; };
105
105
  'CreateProductOptionGroupInput': { kind: 'INPUT_OBJECT'; name: 'CreateProductOptionGroupInput'; isOneOf: false; inputFields: [{ name: 'code'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; }; defaultValue: null }, { name: 'translations'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'ProductOptionGroupTranslationInput'; ofType: null; }; }; }; }; defaultValue: null }, { name: 'options'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'CreateGroupOptionInput'; ofType: null; }; }; }; }; defaultValue: null }, { name: 'customFields'; type: { kind: 'SCALAR'; name: 'JSON'; ofType: null; }; defaultValue: null }]; };
106
106
  'CreateProductOptionInput': { kind: 'INPUT_OBJECT'; name: 'CreateProductOptionInput'; isOneOf: false; inputFields: [{ name: 'productOptionGroupId'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; }; defaultValue: null }, { name: 'code'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; }; defaultValue: null }, { name: 'translations'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'ProductOptionGroupTranslationInput'; ofType: null; }; }; }; }; defaultValue: null }, { name: 'customFields'; type: { kind: 'SCALAR'; name: 'JSON'; ofType: null; }; defaultValue: null }]; };
@@ -280,7 +280,7 @@ export type introspection_types = {
280
280
  'PreviewCollectionVariantsInput': { kind: 'INPUT_OBJECT'; name: 'PreviewCollectionVariantsInput'; isOneOf: false; inputFields: [{ name: 'parentId'; type: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; defaultValue: null }, { name: 'inheritFilters'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; }; defaultValue: null }, { name: 'filters'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'ConfigurableOperationInput'; ofType: null; }; }; }; }; defaultValue: null }]; };
281
281
  'PriceRange': { kind: 'OBJECT'; name: 'PriceRange'; fields: { 'max': { name: 'max'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Money'; ofType: null; }; } }; 'min': { name: 'min'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Money'; ofType: null; }; } }; }; };
282
282
  'Product': { kind: 'OBJECT'; name: 'Product'; fields: { 'assets': { name: 'assets'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'Asset'; ofType: null; }; }; }; } }; 'channels': { name: 'channels'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'Channel'; ofType: null; }; }; }; } }; 'collections': { name: 'collections'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'Collection'; ofType: null; }; }; }; } }; 'createdAt': { name: 'createdAt'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'DateTime'; ofType: null; }; } }; 'customFields': { name: 'customFields'; type: { kind: 'OBJECT'; name: 'ProductCustomFields'; ofType: null; } }; 'description': { name: 'description'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'enabled': { name: 'enabled'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; } }; 'facetValues': { name: 'facetValues'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'FacetValue'; ofType: null; }; }; }; } }; 'featuredAsset': { name: 'featuredAsset'; type: { kind: 'OBJECT'; name: 'Asset'; ofType: null; } }; 'id': { name: 'id'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; } }; 'languageCode': { name: 'languageCode'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'ENUM'; name: 'LanguageCode'; ofType: null; }; } }; 'name': { name: 'name'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'optionGroups': { name: 'optionGroups'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'ProductOptionGroup'; ofType: null; }; }; }; } }; 'reviews': { name: 'reviews'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'ProductReviewList'; ofType: null; }; } }; 'reviewsHistogram': { name: 'reviewsHistogram'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'ProductReviewHistogramItem'; ofType: null; }; }; }; } }; 'slug': { name: 'slug'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'translations': { name: 'translations'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'ProductTranslation'; ofType: null; }; }; }; } }; 'updatedAt': { name: 'updatedAt'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'DateTime'; ofType: null; }; } }; 'variantList': { name: 'variantList'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'ProductVariantList'; ofType: null; }; } }; 'variants': { name: 'variants'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'ProductVariant'; ofType: null; }; }; }; } }; }; };
283
- 'ProductCustomFields': { kind: 'OBJECT'; name: 'ProductCustomFields'; fields: { 'downloadable': { name: 'downloadable'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; } }; 'featuredReview': { name: 'featuredReview'; type: { kind: 'OBJECT'; name: 'ProductReview'; ofType: null; } }; 'infoUrl': { name: 'infoUrl'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'lastUpdated': { name: 'lastUpdated'; type: { kind: 'SCALAR'; name: 'DateTime'; ofType: null; } }; 'reviewCount': { name: 'reviewCount'; type: { kind: 'SCALAR'; name: 'Float'; ofType: null; } }; 'reviewRating': { name: 'reviewRating'; type: { kind: 'SCALAR'; name: 'Float'; ofType: null; } }; 'shortName': { name: 'shortName'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'translatableText': { name: 'translatableText'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; }; };
283
+ 'ProductCustomFields': { kind: 'OBJECT'; name: 'ProductCustomFields'; fields: { 'downloadable': { name: 'downloadable'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; } }; 'featuredReview': { name: 'featuredReview'; type: { kind: 'OBJECT'; name: 'ProductReview'; ofType: null; } }; 'infoUrl': { name: 'infoUrl'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'lastUpdated': { name: 'lastUpdated'; type: { kind: 'SCALAR'; name: 'DateTime'; ofType: null; } }; 'promotedReviews': { name: 'promotedReviews'; type: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'ProductReview'; ofType: null; }; }; } }; 'reviewCount': { name: 'reviewCount'; type: { kind: 'SCALAR'; name: 'Float'; ofType: null; } }; 'reviewRating': { name: 'reviewRating'; type: { kind: 'SCALAR'; name: 'Float'; ofType: null; } }; 'shortName': { name: 'shortName'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'translatableText': { name: 'translatableText'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; }; };
284
284
  'ProductFilterParameter': { kind: 'INPUT_OBJECT'; name: 'ProductFilterParameter'; isOneOf: false; inputFields: [{ name: 'facetValueId'; type: { kind: 'INPUT_OBJECT'; name: 'IDOperators'; ofType: null; }; defaultValue: null }, { name: 'sku'; type: { kind: 'INPUT_OBJECT'; name: 'StringOperators'; ofType: null; }; defaultValue: null }, { name: 'id'; type: { kind: 'INPUT_OBJECT'; name: 'IDOperators'; ofType: null; }; defaultValue: null }, { name: 'createdAt'; type: { kind: 'INPUT_OBJECT'; name: 'DateOperators'; ofType: null; }; defaultValue: null }, { name: 'updatedAt'; type: { kind: 'INPUT_OBJECT'; name: 'DateOperators'; ofType: null; }; defaultValue: null }, { name: 'languageCode'; type: { kind: 'INPUT_OBJECT'; name: 'StringOperators'; ofType: null; }; defaultValue: null }, { name: 'name'; type: { kind: 'INPUT_OBJECT'; name: 'StringOperators'; ofType: null; }; defaultValue: null }, { name: 'slug'; type: { kind: 'INPUT_OBJECT'; name: 'StringOperators'; ofType: null; }; defaultValue: null }, { name: 'description'; type: { kind: 'INPUT_OBJECT'; name: 'StringOperators'; ofType: null; }; defaultValue: null }, { name: 'enabled'; type: { kind: 'INPUT_OBJECT'; name: 'BooleanOperators'; ofType: null; }; defaultValue: null }, { name: '_and'; type: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'ProductFilterParameter'; ofType: null; }; }; }; defaultValue: null }, { name: '_or'; type: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'ProductFilterParameter'; ofType: null; }; }; }; defaultValue: null }, { name: 'infoUrl'; type: { kind: 'INPUT_OBJECT'; name: 'StringOperators'; ofType: null; }; defaultValue: null }, { name: 'downloadable'; type: { kind: 'INPUT_OBJECT'; name: 'BooleanOperators'; ofType: null; }; defaultValue: null }, { name: 'shortName'; type: { kind: 'INPUT_OBJECT'; name: 'StringOperators'; ofType: null; }; defaultValue: null }, { name: 'lastUpdated'; type: { kind: 'INPUT_OBJECT'; name: 'DateOperators'; ofType: null; }; defaultValue: null }, { name: 'reviewRating'; type: { kind: 'INPUT_OBJECT'; name: 'NumberOperators'; ofType: null; }; defaultValue: null }, { name: 'reviewCount'; type: { kind: 'INPUT_OBJECT'; name: 'NumberOperators'; ofType: null; }; defaultValue: null }, { name: 'translatableText'; type: { kind: 'INPUT_OBJECT'; name: 'StringOperators'; ofType: null; }; defaultValue: null }]; };
285
285
  'ProductList': { kind: 'OBJECT'; name: 'ProductList'; fields: { 'items': { name: 'items'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'Product'; ofType: null; }; }; }; } }; 'totalItems': { name: 'totalItems'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Int'; ofType: null; }; } }; }; };
286
286
  'ProductListOptions': { kind: 'INPUT_OBJECT'; name: 'ProductListOptions'; isOneOf: false; inputFields: [{ name: 'skip'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; }; defaultValue: null }, { name: 'take'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; }; defaultValue: null }, { name: 'sort'; type: { kind: 'INPUT_OBJECT'; name: 'ProductSortParameter'; ofType: null; }; defaultValue: null }, { name: 'filter'; type: { kind: 'INPUT_OBJECT'; name: 'ProductFilterParameter'; ofType: null; }; defaultValue: null }, { name: 'filterOperator'; type: { kind: 'ENUM'; name: 'LogicalOperator'; ofType: null; }; defaultValue: null }]; };
@@ -465,7 +465,7 @@ export type introspection_types = {
465
465
  'UpdateOrderItemsResult': { kind: 'UNION'; name: 'UpdateOrderItemsResult'; fields: {}; possibleTypes: 'InsufficientStockError' | 'NegativeQuantityError' | 'Order' | 'OrderInterceptorError' | 'OrderLimitError' | 'OrderModificationError'; };
466
466
  'UpdateOrderNoteInput': { kind: 'INPUT_OBJECT'; name: 'UpdateOrderNoteInput'; isOneOf: false; inputFields: [{ name: 'noteId'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; }; defaultValue: null }, { name: 'note'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; }; defaultValue: null }, { name: 'isPublic'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; defaultValue: null }]; };
467
467
  'UpdatePaymentMethodInput': { kind: 'INPUT_OBJECT'; name: 'UpdatePaymentMethodInput'; isOneOf: false; inputFields: [{ name: 'id'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; }; defaultValue: null }, { name: 'code'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; }; defaultValue: null }, { name: 'enabled'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; defaultValue: null }, { name: 'checker'; type: { kind: 'INPUT_OBJECT'; name: 'ConfigurableOperationInput'; ofType: null; }; defaultValue: null }, { name: 'handler'; type: { kind: 'INPUT_OBJECT'; name: 'ConfigurableOperationInput'; ofType: null; }; defaultValue: null }, { name: 'translations'; type: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'PaymentMethodTranslationInput'; ofType: null; }; }; }; defaultValue: null }, { name: 'customFields'; type: { kind: 'SCALAR'; name: 'JSON'; ofType: null; }; defaultValue: null }]; };
468
- 'UpdateProductCustomFieldsInput': { kind: 'INPUT_OBJECT'; name: 'UpdateProductCustomFieldsInput'; isOneOf: false; inputFields: [{ name: 'infoUrl'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; }; defaultValue: null }, { name: 'downloadable'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; defaultValue: null }, { name: 'lastUpdated'; type: { kind: 'SCALAR'; name: 'DateTime'; ofType: null; }; defaultValue: null }, { name: 'reviewRating'; type: { kind: 'SCALAR'; name: 'Float'; ofType: null; }; defaultValue: null }, { name: 'reviewCount'; type: { kind: 'SCALAR'; name: 'Float'; ofType: null; }; defaultValue: null }, { name: 'featuredReviewId'; type: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; defaultValue: null }]; };
468
+ 'UpdateProductCustomFieldsInput': { kind: 'INPUT_OBJECT'; name: 'UpdateProductCustomFieldsInput'; isOneOf: false; inputFields: [{ name: 'infoUrl'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; }; defaultValue: null }, { name: 'downloadable'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; defaultValue: null }, { name: 'lastUpdated'; type: { kind: 'SCALAR'; name: 'DateTime'; ofType: null; }; defaultValue: null }, { name: 'reviewRating'; type: { kind: 'SCALAR'; name: 'Float'; ofType: null; }; defaultValue: null }, { name: 'reviewCount'; type: { kind: 'SCALAR'; name: 'Float'; ofType: null; }; defaultValue: null }, { name: 'featuredReviewId'; type: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; defaultValue: null }, { name: 'promotedReviewsIds'; type: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; }; }; defaultValue: null }]; };
469
469
  'UpdateProductInput': { kind: 'INPUT_OBJECT'; name: 'UpdateProductInput'; isOneOf: false; inputFields: [{ name: 'id'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; }; defaultValue: null }, { name: 'enabled'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; defaultValue: null }, { name: 'featuredAssetId'; type: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; defaultValue: null }, { name: 'assetIds'; type: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; }; }; defaultValue: null }, { name: 'facetValueIds'; type: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; }; }; defaultValue: null }, { name: 'translations'; type: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'ProductTranslationInput'; ofType: null; }; }; }; defaultValue: null }, { name: 'customFields'; type: { kind: 'INPUT_OBJECT'; name: 'UpdateProductCustomFieldsInput'; ofType: null; }; defaultValue: null }]; };
470
470
  'UpdateProductOptionGroupInput': { kind: 'INPUT_OBJECT'; name: 'UpdateProductOptionGroupInput'; isOneOf: false; inputFields: [{ name: 'id'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; }; defaultValue: null }, { name: 'code'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; }; defaultValue: null }, { name: 'translations'; type: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'ProductOptionGroupTranslationInput'; ofType: null; }; }; }; defaultValue: null }, { name: 'customFields'; type: { kind: 'SCALAR'; name: 'JSON'; ofType: null; }; defaultValue: null }]; };
471
471
  'UpdateProductOptionInput': { kind: 'INPUT_OBJECT'; name: 'UpdateProductOptionInput'; isOneOf: false; inputFields: [{ name: 'id'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; }; defaultValue: null }, { name: 'code'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; }; defaultValue: null }, { name: 'translations'; type: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'ProductOptionGroupTranslationInput'; ofType: null; }; }; }; defaultValue: null }, { name: 'customFields'; type: { kind: 'SCALAR'; name: 'JSON'; ofType: null; }; defaultValue: null }]; };