@wix/auto-patterns 1.27.0 → 1.28.0
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/dist/cjs/dataSourceAdapters/cms/fetchCmsData.js +1 -1
- package/dist/cjs/dataSourceAdapters/cms/fetchCmsData.js.map +1 -1
- package/dist/cjs/hooks/useAutoPatternsOptimisticActions.js +13 -6
- package/dist/cjs/hooks/useAutoPatternsOptimisticActions.js.map +1 -1
- package/dist/cjs/hooks/useBaseCollectionParams.js +38 -0
- package/dist/cjs/hooks/useBaseCollectionParams.js.map +1 -0
- package/dist/cjs/hooks/useCommonCollectionFeatures.js +13 -6
- package/dist/cjs/hooks/useCommonCollectionFeatures.js.map +1 -1
- package/dist/cjs/hooks/useFetchData.js +4 -5
- package/dist/cjs/hooks/useFetchData.js.map +1 -1
- package/dist/cjs/hooks/useGridFeatures.js +6 -26
- package/dist/cjs/hooks/useGridFeatures.js.map +1 -1
- package/dist/cjs/hooks/useTableFeatures.js +6 -26
- package/dist/cjs/hooks/useTableFeatures.js.map +1 -1
- package/dist/cjs/hooks/useTableGridSwitchFeatures.js +8 -28
- package/dist/cjs/hooks/useTableGridSwitchFeatures.js.map +1 -1
- package/dist/cjs/providers/PatternsWizardOverridesContext.js +1 -1
- package/dist/cjs/providers/PatternsWizardOverridesContext.js.map +1 -1
- package/dist/cjs/types/CollectionPageConfig.js.map +1 -1
- package/dist/cjs/types/fetchData.js +4 -0
- package/dist/cjs/types/fetchData.js.map +1 -0
- package/dist/cjs/types/index.js +6 -0
- package/dist/cjs/types/index.js.map +1 -1
- package/dist/cjs/types/types.js.map +1 -1
- package/dist/docs/app_config_structure.md +1 -0
- package/dist/docs/auto-patterns-guide.md +151 -18
- package/dist/docs/custom_overrides.md +1 -15
- package/dist/docs/error_handling.md +135 -0
- package/dist/docs/index.md +4 -0
- package/dist/docs/schema_config.md +11 -3
- package/dist/docs/wix_fqdn_custom_data_source.md +49 -7
- package/dist/esm/dataSourceAdapters/cms/fetchCmsData.js +1 -1
- package/dist/esm/dataSourceAdapters/cms/fetchCmsData.js.map +1 -1
- package/dist/esm/hooks/useAutoPatternsOptimisticActions.js +14 -9
- package/dist/esm/hooks/useAutoPatternsOptimisticActions.js.map +1 -1
- package/dist/esm/hooks/useBaseCollectionParams.js +37 -0
- package/dist/esm/hooks/useBaseCollectionParams.js.map +1 -0
- package/dist/esm/hooks/useCommonCollectionFeatures.js +9 -2
- package/dist/esm/hooks/useCommonCollectionFeatures.js.map +1 -1
- package/dist/esm/hooks/useFetchData.js +2 -2
- package/dist/esm/hooks/useFetchData.js.map +1 -1
- package/dist/esm/hooks/useGridFeatures.js +6 -29
- package/dist/esm/hooks/useGridFeatures.js.map +1 -1
- package/dist/esm/hooks/useTableFeatures.js +6 -29
- package/dist/esm/hooks/useTableFeatures.js.map +1 -1
- package/dist/esm/hooks/useTableGridSwitchFeatures.js +8 -31
- package/dist/esm/hooks/useTableGridSwitchFeatures.js.map +1 -1
- package/dist/esm/providers/PatternsWizardOverridesContext.js.map +1 -1
- package/dist/esm/types/CollectionPageConfig.js.map +1 -1
- package/dist/esm/types/fetchData.js +2 -0
- package/dist/esm/types/fetchData.js.map +1 -0
- package/dist/esm/types/index.js +1 -0
- package/dist/esm/types/index.js.map +1 -1
- package/dist/esm/types/types.js.map +1 -1
- package/dist/types/hooks/useAutoPatternsOptimisticActions.d.ts +7 -1
- package/dist/types/hooks/useAutoPatternsOptimisticActions.d.ts.map +1 -1
- package/dist/types/hooks/useBaseCollectionParams.d.ts +27 -0
- package/dist/types/hooks/useBaseCollectionParams.d.ts.map +1 -0
- package/dist/types/hooks/useCommonCollectionFeatures.d.ts +4 -3
- package/dist/types/hooks/useCommonCollectionFeatures.d.ts.map +1 -1
- package/dist/types/hooks/useFetchData.d.ts +3 -13
- package/dist/types/hooks/useFetchData.d.ts.map +1 -1
- package/dist/types/hooks/useGridFeatures.d.ts +1 -1
- package/dist/types/hooks/useGridFeatures.d.ts.map +1 -1
- package/dist/types/hooks/useTableFeatures.d.ts +1 -1
- package/dist/types/hooks/useTableFeatures.d.ts.map +1 -1
- package/dist/types/hooks/useTableGridSwitchFeatures.d.ts +1 -1
- package/dist/types/hooks/useTableGridSwitchFeatures.d.ts.map +1 -1
- package/dist/types/providers/PatternsWizardOverridesContext.d.ts +2 -1
- package/dist/types/providers/PatternsWizardOverridesContext.d.ts.map +1 -1
- package/dist/types/types/CollectionPageConfig.d.ts +4 -0
- package/dist/types/types/CollectionPageConfig.d.ts.map +1 -1
- package/dist/types/types/fetchData.d.ts +21 -0
- package/dist/types/types/fetchData.d.ts.map +1 -0
- package/dist/types/types/index.d.ts +1 -0
- package/dist/types/types/index.d.ts.map +1 -1
- package/dist/types/types/types.d.ts +5 -5
- package/dist/types/types/types.d.ts.map +1 -1
- package/package.json +9 -9
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["ComponentTypeEnum","exports"],"sources":["../../../src/types/CollectionPageConfig.ts"],"sourcesContent":["import { CollectionToolbarFiltersProps } from '@wix/patterns';\nimport { DateRangeFilterMode, DateRangeOptions } from '@wix/patterns/core';\nimport { BaseCollectionConfig } from './types';\nimport {\n ActionCellConfig,\n BulkActionsConfig,\n CollectionPageOnRowClickActionConfig,\n CollectionPagePrimaryActions,\n CollectionPageSecondaryActions,\n} from './actions';\n\nexport interface CollectionPageTitle {\n text: string;\n hideTotal?: boolean;\n}\n\nexport interface CollectionPageSubtitle {\n text: string;\n learnMore?: {\n url: string;\n label?: string;\n };\n}\n\nexport interface CollectionPageConfig {\n route: {\n path: string;\n };\n title: CollectionPageTitle;\n subtitle?: CollectionPageSubtitle;\n actions?: {\n primaryActions?: CollectionPagePrimaryActions;\n secondaryActions?: CollectionPageSecondaryActions;\n };\n components: ComponentConfig[];\n}\n\nexport interface CollectionComponentConfig\n extends BaseCollectionComponentConfig {\n type: 'collection';\n layout: LayoutItemConfig[];\n}\n\nexport interface CustomComponentConfig {\n type: 'custom';\n id: string;\n}\n\nexport type ComponentConfig = CollectionComponentConfig | CustomComponentConfig;\n\nexport interface LayoutItemConfig {\n type: 'Table' | 'Grid';\n table?: TableSpecificConfig;\n grid?: GridSpecificConfig;\n}\n\nexport type ColumnsConfig = Column[];\n\nexport interface TableSpecificConfig {\n columns: ColumnsConfig;\n customColumns?: {\n enabled: boolean;\n };\n stickyColumns?: number;\n onRowClick?: CollectionPageOnRowClickActionConfig;\n showTitleBar?: boolean;\n sections?: {\n id: string;\n };\n}\n\nexport interface GridSpecificConfig {\n item: GridItem;\n}\n\nexport interface TableConfig\n extends BaseCollectionComponentConfig,\n TableSpecificConfig {}\nexport interface GridConfig\n extends BaseCollectionComponentConfig,\n GridSpecificConfig {}\nexport interface TableGridSwitchConfig\n extends BaseCollectionComponentConfig,\n TableSpecificConfig,\n GridSpecificConfig {}\n\nexport type CollectionConfig = BaseCollectionConfig & {\n limit?: number;\n reflectQueryInUrl?: boolean;\n selectAllScope?: 'page' | 'all';\n selectionUpdateMode?: 'preserve' | 'clear';\n};\n\nexport interface BaseCollectionComponentConfig {\n collection: CollectionConfig;\n entityPageId?: string;\n search?: { shown?: boolean };\n toolbarTitle?: ToolbarTitle;\n actionCell?: ActionCellConfig;\n emptyState?: EmptyState;\n filters?: FiltersConfig;\n bulkActionToolbar?: BulkActionsConfig;\n}\n\nexport interface ToolbarTitle {\n title: string;\n subtitle?: {\n text: string;\n info?: {\n content: {\n text: string;\n link?: {\n url: string;\n label: string;\n };\n };\n };\n learnMore?: {\n url: string;\n label?: string;\n };\n };\n showTotal?: boolean;\n itemsLimit?: number;\n}\n\nexport interface Column {\n id: string;\n name: string;\n width: string;\n sortable?: boolean;\n defaultSortOrder?: 'asc' | 'desc';\n sortMode?: 'asc' | 'desc';\n defaultHidden?: boolean;\n hiddenFromCustomColumnsSelection?: boolean;\n hideable?: boolean;\n reorderDisabled?: boolean;\n}\n\nexport interface GridItem {\n titleFieldId: string;\n subtitleFieldId?: string;\n imageFieldId?: string;\n cardContentMode?: 'full' | 'title' | 'empty'; // Footer is not supported in auto-patterns\n imagePlacement?: 'top' | 'side';\n}\n\nexport interface EmptyState {\n title?: string;\n subtitle?: string;\n image?: {\n id: string;\n };\n addNewCta?: {\n id?: string;\n text?: string;\n };\n customCta?: {\n id?: string;\n };\n}\n\nexport interface FilterOption {\n value: string;\n label: string;\n}\n\nexport type FilterSelectionMode = 'single' | 'multiple';\nexport type FilterOptionType =\n | 'checkbox'\n | 'inlineCheckbox'\n | 'radio'\n | 'select';\n\nexport enum ComponentTypeEnum {\n SINGLE = 'single',\n MULTI_SELECT = 'multi-select',\n RADIO_GROUP = 'radio-group',\n NUMBER = 'number',\n DATE_RANGE = 'date-range',\n}\n\nexport type FilterItems = Filter[];\nexport interface FiltersConfig {\n items: FilterItems;\n maxInlineFilters?: CollectionToolbarFiltersProps['inline'];\n panelTitle?: string;\n}\n\nexport interface BaseOptionsFilterConfig {\n selectionMode: FilterSelectionMode;\n}\n\nexport interface DateFilterConfig {\n mode?: DateRangeFilterMode;\n presets?: DateRangeOptions;\n includeTime?: boolean;\n}\n\nexport interface NumberFilterConfig {\n min?: number;\n max?: number;\n allowedDecimals?: boolean;\n}\n\nexport interface BooleanFilterConfig {\n trueLabel?: string;\n falseLabel?: string;\n}\n\nexport interface EnumFilterConfig extends BaseOptionsFilterConfig {\n options: FilterOption[];\n optionType?: FilterOptionType;\n}\n\nexport interface DynamicOptionsFilterConfig extends BaseOptionsFilterConfig {}\n\nexport interface Filter {\n id: string;\n fieldId: string;\n displayName?: string;\n sectionTitle?: string;\n openByDefault?: boolean;\n tagLabel?: string;\n numberConfig?: NumberFilterConfig;\n dateConfig?: DateFilterConfig;\n booleanConfig?: BooleanFilterConfig;\n enumConfig?: EnumFilterConfig;\n dynamicOptionsConfig?: DynamicOptionsFilterConfig;\n}\n"],"mappings":";;;;
|
|
1
|
+
{"version":3,"names":["ComponentTypeEnum","exports"],"sources":["../../../src/types/CollectionPageConfig.ts"],"sourcesContent":["import { CollectionToolbarFiltersProps } from '@wix/patterns';\nimport { DateRangeFilterMode, DateRangeOptions } from '@wix/patterns/core';\nimport { BaseCollectionConfig } from './types';\nimport {\n ActionCellConfig,\n BulkActionsConfig,\n CollectionPageOnRowClickActionConfig,\n CollectionPagePrimaryActions,\n CollectionPageSecondaryActions,\n} from './actions';\n\nexport interface CollectionPageTitle {\n text: string;\n hideTotal?: boolean;\n}\n\nexport interface CollectionPageSubtitle {\n text: string;\n learnMore?: {\n url: string;\n label?: string;\n };\n}\n\nexport interface CollectionPageConfig {\n route: {\n path: string;\n };\n title: CollectionPageTitle;\n subtitle?: CollectionPageSubtitle;\n actions?: {\n primaryActions?: CollectionPagePrimaryActions;\n secondaryActions?: CollectionPageSecondaryActions;\n };\n components: ComponentConfig[];\n}\n\nexport interface CollectionComponentConfig\n extends BaseCollectionComponentConfig {\n type: 'collection';\n layout: LayoutItemConfig[];\n}\n\nexport interface CustomComponentConfig {\n type: 'custom';\n id: string;\n}\n\nexport type ComponentConfig = CollectionComponentConfig | CustomComponentConfig;\n\nexport interface LayoutItemConfig {\n type: 'Table' | 'Grid';\n table?: TableSpecificConfig;\n grid?: GridSpecificConfig;\n}\n\nexport type ColumnsConfig = Column[];\n\nexport interface TableSpecificConfig {\n columns: ColumnsConfig;\n customColumns?: {\n enabled: boolean;\n };\n stickyColumns?: number;\n onRowClick?: CollectionPageOnRowClickActionConfig;\n showTitleBar?: boolean;\n sections?: {\n id: string;\n };\n}\n\nexport interface GridSpecificConfig {\n item: GridItem;\n}\n\nexport interface TableConfig\n extends BaseCollectionComponentConfig,\n TableSpecificConfig {}\nexport interface GridConfig\n extends BaseCollectionComponentConfig,\n GridSpecificConfig {}\nexport interface TableGridSwitchConfig\n extends BaseCollectionComponentConfig,\n TableSpecificConfig,\n GridSpecificConfig {}\n\nexport type CollectionConfig = BaseCollectionConfig & {\n limit?: number;\n reflectQueryInUrl?: boolean;\n selectAllScope?: 'page' | 'all';\n selectionUpdateMode?: 'preserve' | 'clear';\n optimisticActions?: {\n id: string;\n };\n paginationMode?: 'cursor' | 'offset';\n};\n\nexport interface BaseCollectionComponentConfig {\n collection: CollectionConfig;\n entityPageId?: string;\n search?: { shown?: boolean };\n toolbarTitle?: ToolbarTitle;\n actionCell?: ActionCellConfig;\n emptyState?: EmptyState;\n filters?: FiltersConfig;\n bulkActionToolbar?: BulkActionsConfig;\n}\n\nexport interface ToolbarTitle {\n title: string;\n subtitle?: {\n text: string;\n info?: {\n content: {\n text: string;\n link?: {\n url: string;\n label: string;\n };\n };\n };\n learnMore?: {\n url: string;\n label?: string;\n };\n };\n showTotal?: boolean;\n itemsLimit?: number;\n}\n\nexport interface Column {\n id: string;\n name: string;\n width: string;\n sortable?: boolean;\n defaultSortOrder?: 'asc' | 'desc';\n sortMode?: 'asc' | 'desc';\n defaultHidden?: boolean;\n hiddenFromCustomColumnsSelection?: boolean;\n hideable?: boolean;\n reorderDisabled?: boolean;\n}\n\nexport interface GridItem {\n titleFieldId: string;\n subtitleFieldId?: string;\n imageFieldId?: string;\n cardContentMode?: 'full' | 'title' | 'empty'; // Footer is not supported in auto-patterns\n imagePlacement?: 'top' | 'side';\n}\n\nexport interface EmptyState {\n title?: string;\n subtitle?: string;\n image?: {\n id: string;\n };\n addNewCta?: {\n id?: string;\n text?: string;\n };\n customCta?: {\n id?: string;\n };\n}\n\nexport interface FilterOption {\n value: string;\n label: string;\n}\n\nexport type FilterSelectionMode = 'single' | 'multiple';\nexport type FilterOptionType =\n | 'checkbox'\n | 'inlineCheckbox'\n | 'radio'\n | 'select';\n\nexport enum ComponentTypeEnum {\n SINGLE = 'single',\n MULTI_SELECT = 'multi-select',\n RADIO_GROUP = 'radio-group',\n NUMBER = 'number',\n DATE_RANGE = 'date-range',\n}\n\nexport type FilterItems = Filter[];\nexport interface FiltersConfig {\n items: FilterItems;\n maxInlineFilters?: CollectionToolbarFiltersProps['inline'];\n panelTitle?: string;\n}\n\nexport interface BaseOptionsFilterConfig {\n selectionMode: FilterSelectionMode;\n}\n\nexport interface DateFilterConfig {\n mode?: DateRangeFilterMode;\n presets?: DateRangeOptions;\n includeTime?: boolean;\n}\n\nexport interface NumberFilterConfig {\n min?: number;\n max?: number;\n allowedDecimals?: boolean;\n}\n\nexport interface BooleanFilterConfig {\n trueLabel?: string;\n falseLabel?: string;\n}\n\nexport interface EnumFilterConfig extends BaseOptionsFilterConfig {\n options: FilterOption[];\n optionType?: FilterOptionType;\n}\n\nexport interface DynamicOptionsFilterConfig extends BaseOptionsFilterConfig {}\n\nexport interface Filter {\n id: string;\n fieldId: string;\n displayName?: string;\n sectionTitle?: string;\n openByDefault?: boolean;\n tagLabel?: string;\n numberConfig?: NumberFilterConfig;\n dateConfig?: DateFilterConfig;\n booleanConfig?: BooleanFilterConfig;\n enumConfig?: EnumFilterConfig;\n dynamicOptionsConfig?: DynamicOptionsFilterConfig;\n}\n"],"mappings":";;;;IAkLYA,iBAAiB,GAAAC,OAAA,CAAAD,iBAAA,0BAAjBA,iBAAiB;EAAjBA,iBAAiB;EAAjBA,iBAAiB;EAAjBA,iBAAiB;EAAjBA,iBAAiB;EAAjBA,iBAAiB;EAAA,OAAjBA,iBAAiB;AAAA","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":["../../../src/types/fetchData.ts"],"sourcesContent":["import { CursorQuery, OffsetQuery } from '@wix/patterns';\n\nexport type Mode = 'cursor' | 'offset';\n\nexport type UseFetchDataProps<M extends Mode> = {\n searchableFieldIds?: string[];\n filterFieldMapping?: Record<string, { fieldId: string }>;\n paginationMode?: M;\n};\n\nexport interface CursorQueryResult {\n items: any[];\n cursor?: string | undefined | null;\n total?: number | null;\n}\n\nexport interface OffsetQueryResult {\n items: any[];\n total?: number | null;\n hasNext?: boolean;\n}\n\nexport type FetchDataFn<M extends Mode> = M extends 'cursor'\n ? (q: CursorQuery<any>) => Promise<CursorQueryResult>\n : (q: OffsetQuery<any>) => Promise<OffsetQueryResult>;\n"],"mappings":"","ignoreList":[]}
|
package/dist/cjs/types/index.js
CHANGED
|
@@ -43,4 +43,10 @@ Object.keys(_BaseSDK).forEach(function (key) {
|
|
|
43
43
|
if (key in exports && exports[key] === _BaseSDK[key]) return;
|
|
44
44
|
exports[key] = _BaseSDK[key];
|
|
45
45
|
});
|
|
46
|
+
var _fetchData = require("./fetchData");
|
|
47
|
+
Object.keys(_fetchData).forEach(function (key) {
|
|
48
|
+
if (key === "default" || key === "__esModule") return;
|
|
49
|
+
if (key in exports && exports[key] === _fetchData[key]) return;
|
|
50
|
+
exports[key] = _fetchData[key];
|
|
51
|
+
});
|
|
46
52
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_types","require","Object","keys","forEach","key","exports","_CollectionPageConfig","_EntityPageConfig","_providers","_actions","_types2","_BaseSDK"],"sources":["../../../src/types/index.ts"],"sourcesContent":["export * from './types';\nexport * from './CollectionPageConfig';\nexport * from './EntityPageConfig';\nexport * from './providers';\nexport * from './actions';\nexport * from '../utils/actions/types';\nexport * from './BaseSDK';\n"],"mappings":";;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAH,MAAA,EAAAI,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAL,MAAA,CAAAK,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAL,MAAA,CAAAK,GAAA;AAAA;AACA,IAAAE,qBAAA,GAAAN,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAI,qBAAA,EAAAH,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAE,qBAAA,CAAAF,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAE,qBAAA,CAAAF,GAAA;AAAA;AACA,IAAAG,iBAAA,GAAAP,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAK,iBAAA,EAAAJ,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAG,iBAAA,CAAAH,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAG,iBAAA,CAAAH,GAAA;AAAA;AACA,IAAAI,UAAA,GAAAR,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAM,UAAA,EAAAL,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAI,UAAA,CAAAJ,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAI,UAAA,CAAAJ,GAAA;AAAA;AACA,IAAAK,QAAA,GAAAT,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAO,QAAA,EAAAN,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAK,QAAA,CAAAL,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAK,QAAA,CAAAL,GAAA;AAAA;AACA,IAAAM,OAAA,GAAAV,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAQ,OAAA,EAAAP,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAM,OAAA,CAAAN,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAM,OAAA,CAAAN,GAAA;AAAA;AACA,IAAAO,QAAA,GAAAX,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAS,QAAA,EAAAR,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAO,QAAA,CAAAP,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAO,QAAA,CAAAP,GAAA;AAAA","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["_types","require","Object","keys","forEach","key","exports","_CollectionPageConfig","_EntityPageConfig","_providers","_actions","_types2","_BaseSDK","_fetchData"],"sources":["../../../src/types/index.ts"],"sourcesContent":["export * from './types';\nexport * from './CollectionPageConfig';\nexport * from './EntityPageConfig';\nexport * from './providers';\nexport * from './actions';\nexport * from '../utils/actions/types';\nexport * from './BaseSDK';\nexport * from './fetchData';\n"],"mappings":";;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAH,MAAA,EAAAI,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAL,MAAA,CAAAK,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAL,MAAA,CAAAK,GAAA;AAAA;AACA,IAAAE,qBAAA,GAAAN,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAI,qBAAA,EAAAH,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAE,qBAAA,CAAAF,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAE,qBAAA,CAAAF,GAAA;AAAA;AACA,IAAAG,iBAAA,GAAAP,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAK,iBAAA,EAAAJ,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAG,iBAAA,CAAAH,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAG,iBAAA,CAAAH,GAAA;AAAA;AACA,IAAAI,UAAA,GAAAR,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAM,UAAA,EAAAL,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAI,UAAA,CAAAJ,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAI,UAAA,CAAAJ,GAAA;AAAA;AACA,IAAAK,QAAA,GAAAT,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAO,QAAA,EAAAN,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAK,QAAA,CAAAL,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAK,QAAA,CAAAL,GAAA;AAAA;AACA,IAAAM,OAAA,GAAAV,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAQ,OAAA,EAAAP,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAM,OAAA,CAAAN,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAM,OAAA,CAAAN,GAAA;AAAA;AACA,IAAAO,QAAA,GAAAX,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAS,QAAA,EAAAR,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAO,QAAA,CAAAP,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAO,QAAA,CAAAP,GAAA;AAAA;AACA,IAAAQ,UAAA,GAAAZ,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAU,UAAA,EAAAT,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAQ,UAAA,CAAAR,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAQ,UAAA,CAAAR,GAAA;AAAA","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["../../../src/types/types.ts"],"sourcesContent":["import { EntityPageConfig } from './EntityPageConfig';\nimport { CollectionPageConfig } from './CollectionPageConfig';\n\ninterface BaseCollectionConfigCommon {\n collectionId: string;\n}\n\ninterface CMSCollectionConfig extends BaseCollectionConfigCommon {\n entityTypeSource: 'cms';\n custom?: never;\n}\n\ninterface CustomCollectionConfig extends BaseCollectionConfigCommon {\n entityTypeSource: 'custom';\n custom: {\n id: string;\n };\n}\n\nexport type BaseCollectionConfig = CMSCollectionConfig | CustomCollectionConfig;\n\nexport type PatternsFieldType =\n | 'SHORT_TEXT'\n | 'LONG_TEXT'\n | 'NUMBER'\n | 'BOOLEAN'\n | 'DATE'\n | 'DATETIME'\n | 'URL'\n | 'ARRAY'\n | 'REFERENCE'\n | 'IMAGE';\n\nexport interface AppConfig {\n pages: PageConfig[];\n layout?: 'panel';\n}\n\nexport interface BasePageConfig {\n id: string;\n appMainPage?: boolean;\n}\n\nexport interface CollectionPageConfigType extends BasePageConfig {\n type: 'collectionPage';\n collectionPage: CollectionPageConfig;\n entityPage?: never;\n}\n\nexport interface EntityPageConfigType extends BasePageConfig {\n type: 'entityPage';\n entityPage: EntityPageConfig;\n collectionPage?: never;\n}\n\nexport type PageConfig = CollectionPageConfigType | EntityPageConfigType;\n\nexport type EntityProps = { [key: string]: any };\n\nexport interface IMenuItem<T extends EntityProps = any> {\n item: T;\n}\nexport interface IColumnValue<T> {\n value: T;\n row: Record<string, any>;\n}\n\nexport type QueryOperator =\n | 'CONTAINS'\n | 'ENDS_WITH'\n | 'EQ'\n | 'EXISTS'\n | 'GT'\n | 'GTE'\n | 'HAS_ALL'\n | 'HAS_SOME'\n | 'LT'\n | 'LTE'\n | 'NE'\n | 'STARTS_WITH'\n | 'URLIZED';\n\ninterface BaseField {\n id: string;\n displayName: string;\n validation?: {\n numberRange?: NumberRange;\n stringLengthRange?: StringLengthRange;\n required: boolean;\n };\n capabilities: {\n supportedQueryOperators: QueryOperator[];\n sortable: boolean;\n };\n}\n\nexport interface ReferenceField extends BaseField {\n type: 'REFERENCE';\n referenceMetadata: {\n referencedCollectionId: string;\n };\n}\n\nexport interface NonReferenceField extends BaseField {\n type: Exclude<PatternsFieldType, 'REFERENCE'>;\n}\n\nexport type Field = ReferenceField | NonReferenceField;\n\nexport interface NumberRange {\n min?: number;\n max?: number;\n}\nexport interface StringLengthRange {\n minLength?: number;\n maxLength?: number;\n}\n\nexport interface Query {\n limit: number;\n offset
|
|
1
|
+
{"version":3,"names":[],"sources":["../../../src/types/types.ts"],"sourcesContent":["import { EntityPageConfig } from './EntityPageConfig';\nimport { CollectionPageConfig } from './CollectionPageConfig';\nimport { useOptimisticActions } from '@wix/patterns';\nimport { CursorQueryResult, OffsetQueryResult } from './fetchData';\n\ninterface BaseCollectionConfigCommon {\n collectionId: string;\n}\n\ninterface CMSCollectionConfig extends BaseCollectionConfigCommon {\n entityTypeSource: 'cms';\n custom?: never;\n}\n\ninterface CustomCollectionConfig extends BaseCollectionConfigCommon {\n entityTypeSource: 'custom';\n custom: {\n id: string;\n };\n}\n\nexport type BaseCollectionConfig = CMSCollectionConfig | CustomCollectionConfig;\n\nexport type PatternsFieldType =\n | 'SHORT_TEXT'\n | 'LONG_TEXT'\n | 'NUMBER'\n | 'BOOLEAN'\n | 'DATE'\n | 'DATETIME'\n | 'URL'\n | 'ARRAY'\n | 'REFERENCE'\n | 'IMAGE';\n\nexport interface AppConfig {\n pages: PageConfig[];\n layout?: 'panel';\n}\n\nexport interface BasePageConfig {\n id: string;\n appMainPage?: boolean;\n}\n\nexport interface CollectionPageConfigType extends BasePageConfig {\n type: 'collectionPage';\n collectionPage: CollectionPageConfig;\n entityPage?: never;\n}\n\nexport interface EntityPageConfigType extends BasePageConfig {\n type: 'entityPage';\n entityPage: EntityPageConfig;\n collectionPage?: never;\n}\n\nexport type PageConfig = CollectionPageConfigType | EntityPageConfigType;\n\nexport type EntityProps = { [key: string]: any };\n\nexport interface IMenuItem<T extends EntityProps = any> {\n item: T;\n}\nexport interface IColumnValue<T> {\n value: T;\n row: Record<string, any>;\n}\n\nexport type QueryOperator =\n | 'CONTAINS'\n | 'ENDS_WITH'\n | 'EQ'\n | 'EXISTS'\n | 'GT'\n | 'GTE'\n | 'HAS_ALL'\n | 'HAS_SOME'\n | 'LT'\n | 'LTE'\n | 'NE'\n | 'STARTS_WITH'\n | 'URLIZED';\n\ninterface BaseField {\n id: string;\n displayName: string;\n validation?: {\n numberRange?: NumberRange;\n stringLengthRange?: StringLengthRange;\n required: boolean;\n };\n capabilities: {\n supportedQueryOperators: QueryOperator[];\n sortable: boolean;\n };\n}\n\nexport interface ReferenceField extends BaseField {\n type: 'REFERENCE';\n referenceMetadata: {\n referencedCollectionId: string;\n };\n}\n\nexport interface NonReferenceField extends BaseField {\n type: Exclude<PatternsFieldType, 'REFERENCE'>;\n}\n\nexport type Field = ReferenceField | NonReferenceField;\n\nexport interface NumberRange {\n min?: number;\n max?: number;\n}\nexport interface StringLengthRange {\n minLength?: number;\n maxLength?: number;\n}\n\nexport interface Query {\n limit: number;\n offset?: number;\n page: number;\n search?: string;\n cursor?: string | null;\n filters: Record<string, any>;\n sort?: {\n fieldName: string;\n order: 'asc' | 'desc';\n }[];\n}\nexport interface SchemaConfig {\n id: string;\n fields: Record<string, Field | undefined>;\n displayField: string;\n idField: string;\n actions: {\n get: (entityId: string) => Promise<any>;\n create: (newEntity: Partial<any>) => Promise<any>;\n update: (updatedEntity: any) => Promise<any>;\n delete: (entityId: string) => Promise<any>;\n bulkDelete: (entityIds: string[]) => Promise<any>;\n find: (\n query: Query,\n options?: {\n searchableFieldIds?: string[];\n filterFieldMapping?: Record<string, { fieldId: string }>;\n },\n ) => Promise<CursorQueryResult | OffsetQueryResult>;\n };\n}\n\nexport type OptimisticActionsParams = Parameters<\n typeof useOptimisticActions\n>[1];\n"],"mappings":"","ignoreList":[]}
|
|
@@ -89,6 +89,7 @@ export interface AppConfig {
|
|
|
89
89
|
reflectQueryInUrl?: boolean; // Reflects query state (search, filters, sorting) in the browser URL. Default: false
|
|
90
90
|
selectAllScope?: 'page' | 'all'; // Controls "Select All" scope. 'all' selects entire collection, 'page' selects only visible items. Default: 'all'
|
|
91
91
|
selectionUpdateMode?: 'preserve' | 'clear'; // Controls selection behavior when data changes. 'preserve' maintains selections, 'clear' clears them. Default: 'clear'
|
|
92
|
+
paginationMode?: 'cursor' | 'offset'; // Controls pagination strategy and expected find() return shape. 'cursor' => { items, cursor, total? }, 'offset' (default) => { items, hasNext, total? }
|
|
92
93
|
};
|
|
93
94
|
filters?: {
|
|
94
95
|
panelTitle?: string; // Title of the filters panel
|
|
@@ -167,6 +167,7 @@ export interface AppConfig {
|
|
|
167
167
|
reflectQueryInUrl?: boolean; // Reflects query state (search, filters, sorting) in the browser URL. Default: false
|
|
168
168
|
selectAllScope?: 'page' | 'all'; // Controls "Select All" scope. 'all' selects entire collection, 'page' selects only visible items. Default: 'all'
|
|
169
169
|
selectionUpdateMode?: 'preserve' | 'clear'; // Controls selection behavior when data changes. 'preserve' maintains selections, 'clear' clears them. Default: 'clear'
|
|
170
|
+
paginationMode?: 'cursor' | 'offset'; // Controls pagination strategy and expected find() return shape. 'cursor' => { items, cursor, total? }, 'offset' (default) => { items, hasNext, total? }
|
|
170
171
|
};
|
|
171
172
|
filters?: {
|
|
172
173
|
panelTitle?: string; // Title of the filters panel
|
|
@@ -1235,19 +1236,25 @@ export interface SchemaConfig {
|
|
|
1235
1236
|
update: (updatedEntity: any) => Promise<any>;
|
|
1236
1237
|
delete: (entityId: string) => Promise<any>;
|
|
1237
1238
|
bulkDelete: (entityIds: string[]) => Promise<any>;
|
|
1239
|
+
// The return shape depends on pagination mode (see AppConfig.collection.paginationMode)
|
|
1240
|
+
// - Cursor mode: { items, cursor, total? }
|
|
1241
|
+
// - Offset mode (default): { items, hasNext, total? }
|
|
1238
1242
|
find: (
|
|
1239
1243
|
query: Query,
|
|
1240
1244
|
options?: {
|
|
1241
1245
|
searchableFieldIds?: string[];
|
|
1242
1246
|
filterFieldMapping?: Record<string, { fieldId: string }>;
|
|
1243
1247
|
},
|
|
1244
|
-
) => Promise<
|
|
1248
|
+
) => Promise<
|
|
1249
|
+
| { items: any[]; cursor?: string | null; total?: number | null }
|
|
1250
|
+
| { items: any[]; hasNext?: boolean; total?: number | null }
|
|
1251
|
+
>;
|
|
1245
1252
|
};
|
|
1246
1253
|
}
|
|
1247
1254
|
|
|
1248
1255
|
export interface Query {
|
|
1249
1256
|
limit: number; // Maximum number of items to return per request (controls page size)
|
|
1250
|
-
offset
|
|
1257
|
+
offset?: number; // Number of items to skip from the beginning (for pagination)
|
|
1251
1258
|
page: number; // Current page number (1-based, works with limit for pagination)
|
|
1252
1259
|
search?: string; // Text search query applied to searchable fields
|
|
1253
1260
|
cursor?: string | null; // Cursor-based pagination token (alternative to offset-based pagination)
|
|
@@ -1346,7 +1353,9 @@ export type Field = ReferenceField | NonReferenceField;
|
|
|
1346
1353
|
- `query`: Query object with pagination, filtering, sorting, and search criteria (see Query Interface section)
|
|
1347
1354
|
- `options.searchableFieldIds`: Array of field IDs that support text search
|
|
1348
1355
|
- `options.filterFieldMapping`: Maps filter IDs to actual field IDs for complex filtering
|
|
1349
|
-
- Returns
|
|
1356
|
+
- Returns (depends on pagination mode):
|
|
1357
|
+
- Cursor mode: `{ items: any[]; cursor?: string | null; total?: number | null }`
|
|
1358
|
+
- Offset mode (default): `{ items: any[]; hasNext?: boolean; total?: number | null }`
|
|
1350
1359
|
|
|
1351
1360
|
### Field Type Information
|
|
1352
1361
|
|
|
@@ -2833,6 +2842,7 @@ export default withDashboard(Index);
|
|
|
2833
2842
|
|
|
2834
2843
|
- **Custom overrides are restricted to the defined areas only** - attempting to override or modify any other aspect of `AutoPatternsApp` is prohibited and can cause unexpected behavior
|
|
2835
2844
|
- **Always verify override implementation** - when implementing custom overrides, you MUST ensure they are correctly imported and passed to the `PatternsWizardOverridesProvider`
|
|
2845
|
+
- **CRITICAL: Error handling for custom actions** - Custom actions that make external API calls (using `fetch()`, `axios`, etc.) should NOT use `errorHandler.withErrorHandler`. Only Wix HTTP requests (httpClient from @wix/essentials, Wix APIs like wix/data and wix/stores, and httpClient.fetchWithAuth()) require errorHandler wrapping. See the "Error Handling for HTTP Requests" section for details.
|
|
2836
2846
|
|
|
2837
2847
|
The `PatternsWizardOverridesProvider` allows you to inject custom code to override default behaviors or add additional functionality. Below are the areas where overrides can be applied:
|
|
2838
2848
|
|
|
@@ -3639,22 +3649,7 @@ When implementing custom data sources, you need to map your data source field ty
|
|
|
3639
3649
|
- **Reference fields** → `'REFERENCE'`
|
|
3640
3650
|
- **URL fields** → `'URL'`
|
|
3641
3651
|
|
|
3642
|
-
### Error Handling
|
|
3643
3652
|
|
|
3644
|
-
Custom data sources should include proper error handling:
|
|
3645
|
-
|
|
3646
|
-
```tsx
|
|
3647
|
-
actions: {
|
|
3648
|
-
get: async (entityId: string) => {
|
|
3649
|
-
try {
|
|
3650
|
-
const result = await yourDataSourceCall(entityId);
|
|
3651
|
-
return result;
|
|
3652
|
-
} catch (error) {
|
|
3653
|
-
throw new Error(`Failed to fetch entity: ${error.message}`);
|
|
3654
|
-
}
|
|
3655
|
-
}
|
|
3656
|
-
}
|
|
3657
|
-
```
|
|
3658
3653
|
|
|
3659
3654
|
### Validation Requirements
|
|
3660
3655
|
|
|
@@ -4001,3 +3996,141 @@ export default function YourPage() {
|
|
|
4001
3996
|
Slots provide a powerful way to enhance collection pages with custom functionality while maintaining the structure and features of the AutoPatterns system.
|
|
4002
3997
|
|
|
4003
3998
|
---
|
|
3999
|
+
|
|
4000
|
+
# Error Handling for HTTP Requests
|
|
4001
|
+
|
|
4002
|
+
**⚠️ CRITICAL**: When implementing custom data sources that make HTTP requests, you **MUST** wrap specific HTTP calls with proper error handling. This ensures consistent error management, prevents unhandled promise rejections, and provides better user experience.
|
|
4003
|
+
|
|
4004
|
+
## What Requires Error Handling
|
|
4005
|
+
|
|
4006
|
+
**ONLY the following HTTP requests** in your custom data source actions must be wrapped with `errorHandler`:
|
|
4007
|
+
|
|
4008
|
+
- **httpClient from @wix/essentials** (e.g., `httpClient.request(getDummyEntity(...))`)
|
|
4009
|
+
- **Wix APIs** (e.g., `wix/data`, `wix/stores`, `items.get()`, `items.insert()`, `collections.getDataCollection()`)
|
|
4010
|
+
- **httpClient.fetchWithAuth()** calls
|
|
4011
|
+
|
|
4012
|
+
**DO NOT use errorHandler with:**
|
|
4013
|
+
|
|
4014
|
+
- **External API calls** using `fetch()`, `axios.get()`, or other HTTP libraries
|
|
4015
|
+
- **Custom HTTP clients** (e.g., any non-Wix HTTP request library)
|
|
4016
|
+
- **Third-party API calls** using non-Wix HTTP methods
|
|
4017
|
+
|
|
4018
|
+
**EXCEPTION**: SDK actions that you get from the AutoPatterns SDK (e.g., `sdk.getOptimisticActions()`, `sdk.getSchema()`) do NOT need error handling as they are already handled internally.
|
|
4019
|
+
|
|
4020
|
+
## Why Error Handling is Required
|
|
4021
|
+
|
|
4022
|
+
Custom data sources often make HTTP requests to Wix APIs and services. Without proper error handling:
|
|
4023
|
+
|
|
4024
|
+
- **Unhandled Promise Rejections**: HTTP failures can crash your application
|
|
4025
|
+
- **Poor User Experience**: Users don't get meaningful error messages
|
|
4026
|
+
- **Inconsistent Error Management**: Different parts of your app handle errors differently
|
|
4027
|
+
- **Debugging Difficulties**: Hard to trace and diagnose API failures
|
|
4028
|
+
|
|
4029
|
+
## Using @wix/essentials errorHandler
|
|
4030
|
+
|
|
4031
|
+
The recommended approach is to use the `errorHandler` from `@wix/essentials` package, which provides consistent error handling patterns across Wix applications.
|
|
4032
|
+
|
|
4033
|
+
### Installation
|
|
4034
|
+
|
|
4035
|
+
First, ensure `@wix/essentials` is installed in your project:
|
|
4036
|
+
|
|
4037
|
+
```bash
|
|
4038
|
+
npm install @wix/essentials
|
|
4039
|
+
```
|
|
4040
|
+
|
|
4041
|
+
### Basic Error Handling Pattern
|
|
4042
|
+
|
|
4043
|
+
Wrap Wix HTTP requests in your custom data source actions with `errorHandler.withErrorHandler`:
|
|
4044
|
+
|
|
4045
|
+
```typescript
|
|
4046
|
+
import { errorHandler } from '@wix/essentials';
|
|
4047
|
+
|
|
4048
|
+
// In your custom data source actions
|
|
4049
|
+
actions: {
|
|
4050
|
+
get: async (entityId: string) => {
|
|
4051
|
+
return errorHandler.withErrorHandler(
|
|
4052
|
+
async () => {
|
|
4053
|
+
const response = await httpClient.request(
|
|
4054
|
+
getDummyEntity({ dummyEntityId: entityId })
|
|
4055
|
+
);
|
|
4056
|
+
return response.data.dummyEntity;
|
|
4057
|
+
},
|
|
4058
|
+
{}
|
|
4059
|
+
);
|
|
4060
|
+
},
|
|
4061
|
+
}
|
|
4062
|
+
```
|
|
4063
|
+
|
|
4064
|
+
### Examples of HTTP Requests That Need Error Handling
|
|
4065
|
+
|
|
4066
|
+
**httpClient from @wix/essentials:**
|
|
4067
|
+
|
|
4068
|
+
```typescript
|
|
4069
|
+
return errorHandler.withErrorHandler(async () => {
|
|
4070
|
+
const response = await httpClient.request(
|
|
4071
|
+
getDummyEntity({ dummyEntityId: entityId })
|
|
4072
|
+
);
|
|
4073
|
+
return response.data.dummyEntity;
|
|
4074
|
+
}, {});
|
|
4075
|
+
```
|
|
4076
|
+
|
|
4077
|
+
**Wix APIs (wix/data, wix/stores):**
|
|
4078
|
+
|
|
4079
|
+
```typescript
|
|
4080
|
+
return errorHandler.withErrorHandler(async () => {
|
|
4081
|
+
return await items.get(collectionId, entityId);
|
|
4082
|
+
}, {});
|
|
4083
|
+
```
|
|
4084
|
+
|
|
4085
|
+
**httpClient.fetchWithAuth() calls:**
|
|
4086
|
+
|
|
4087
|
+
```typescript
|
|
4088
|
+
return errorHandler.withErrorHandler(async () => {
|
|
4089
|
+
const response = await httpClient.fetchWithAuth("/api/data");
|
|
4090
|
+
return await response.json();
|
|
4091
|
+
}, {});
|
|
4092
|
+
```
|
|
4093
|
+
|
|
4094
|
+
### Examples of HTTP Requests That Do NOT Need Error Handling
|
|
4095
|
+
|
|
4096
|
+
**External API calls (using fetch, axios, etc.):**
|
|
4097
|
+
|
|
4098
|
+
```typescript
|
|
4099
|
+
// ✅ CORRECT - No error handling needed for external APIs
|
|
4100
|
+
const response = await fetch("https://api.example.com/data");
|
|
4101
|
+
return await response.json();
|
|
4102
|
+
|
|
4103
|
+
// ✅ CORRECT - No error handling needed for axios
|
|
4104
|
+
const response = await axios.get("https://api.example.com/data");
|
|
4105
|
+
return response.data;
|
|
4106
|
+
```
|
|
4107
|
+
|
|
4108
|
+
**Third-party HTTP libraries:**
|
|
4109
|
+
|
|
4110
|
+
```typescript
|
|
4111
|
+
// ✅ CORRECT - No error handling needed for third-party HTTP clients
|
|
4112
|
+
const response = await someThirdPartyHttpClient.get("/data");
|
|
4113
|
+
return response.data;
|
|
4114
|
+
```
|
|
4115
|
+
|
|
4116
|
+
## Integration with AutoPatterns Error Handling
|
|
4117
|
+
|
|
4118
|
+
The error handling in your custom data source integrates seamlessly with AutoPatterns' built-in error handling:
|
|
4119
|
+
|
|
4120
|
+
1. **User-Friendly Messages**: Errors are displayed to users in a consistent format
|
|
4121
|
+
2. **Retry Mechanisms**: Users can retry failed operations
|
|
4122
|
+
3. **Loading States**: Proper loading states during HTTP requests
|
|
4123
|
+
4. **Error Boundaries**: Errors are caught and handled gracefully
|
|
4124
|
+
|
|
4125
|
+
## Validation Checklist
|
|
4126
|
+
|
|
4127
|
+
Before deploying your custom data source, ensure:
|
|
4128
|
+
|
|
4129
|
+
✅ **httpClient from @wix/essentials** is wrapped with `errorHandler.withErrorHandler`
|
|
4130
|
+
✅ **Wix APIs (wix/data, wix/stores, etc)** are wrapped with `errorHandler.withErrorHandler`
|
|
4131
|
+
✅ **httpClient.fetchWithAuth()** calls are wrapped with `errorHandler.withErrorHandler`
|
|
4132
|
+
✅ **External API calls are NOT wrapped** with errorHandler (e.g., fetch(), axios, third-party HTTP clients)
|
|
4133
|
+
✅ **SDK actions are used directly** without error handling (e.g., `sdk.getOptimisticActions()`, `sdk.getSchema()`)
|
|
4134
|
+
✅ **@wix/essentials** is installed as a dependency
|
|
4135
|
+
|
|
4136
|
+
---
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
- **Custom overrides are restricted to the defined areas only** - attempting to override or modify any other aspect of `AutoPatternsApp` is prohibited and can cause unexpected behavior
|
|
6
6
|
- **Always verify override implementation** - when implementing custom overrides, you MUST ensure they are correctly imported and passed to the `PatternsWizardOverridesProvider`
|
|
7
|
+
- **CRITICAL: Error handling for custom actions** - Custom actions that make external API calls (using `fetch()`, `axios`, etc.) should NOT use `errorHandler.withErrorHandler`. Only Wix HTTP requests (httpClient from @wix/essentials, Wix APIs like wix/data and wix/stores, and httpClient.fetchWithAuth()) require errorHandler wrapping. See the "Error Handling for HTTP Requests" section for details.
|
|
7
8
|
|
|
8
9
|
The `PatternsWizardOverridesProvider` allows you to inject custom code to override default behaviors or add additional functionality. Below are the areas where overrides can be applied:
|
|
9
10
|
|
|
@@ -810,22 +811,7 @@ When implementing custom data sources, you need to map your data source field ty
|
|
|
810
811
|
- **Reference fields** → `'REFERENCE'`
|
|
811
812
|
- **URL fields** → `'URL'`
|
|
812
813
|
|
|
813
|
-
### Error Handling
|
|
814
814
|
|
|
815
|
-
Custom data sources should include proper error handling:
|
|
816
|
-
|
|
817
|
-
```tsx
|
|
818
|
-
actions: {
|
|
819
|
-
get: async (entityId: string) => {
|
|
820
|
-
try {
|
|
821
|
-
const result = await yourDataSourceCall(entityId);
|
|
822
|
-
return result;
|
|
823
|
-
} catch (error) {
|
|
824
|
-
throw new Error(`Failed to fetch entity: ${error.message}`);
|
|
825
|
-
}
|
|
826
|
-
}
|
|
827
|
-
}
|
|
828
|
-
```
|
|
829
815
|
|
|
830
816
|
### Validation Requirements
|
|
831
817
|
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Error Handling for HTTP Requests
|
|
2
|
+
|
|
3
|
+
**⚠️ CRITICAL**: When implementing custom data sources that make HTTP requests, you **MUST** wrap specific HTTP calls with proper error handling. This ensures consistent error management, prevents unhandled promise rejections, and provides better user experience.
|
|
4
|
+
|
|
5
|
+
## What Requires Error Handling
|
|
6
|
+
|
|
7
|
+
**ONLY the following HTTP requests** in your custom data source actions must be wrapped with `errorHandler`:
|
|
8
|
+
|
|
9
|
+
- **httpClient from @wix/essentials** (e.g., `httpClient.request(getDummyEntity(...))`)
|
|
10
|
+
- **Wix APIs** (e.g., `wix/data`, `wix/stores`, `items.get()`, `items.insert()`, `collections.getDataCollection()`)
|
|
11
|
+
- **httpClient.fetchWithAuth()** calls
|
|
12
|
+
|
|
13
|
+
**DO NOT use errorHandler with:**
|
|
14
|
+
|
|
15
|
+
- **External API calls** using `fetch()`, `axios.get()`, or other HTTP libraries
|
|
16
|
+
- **Custom HTTP clients** (e.g., any non-Wix HTTP request library)
|
|
17
|
+
- **Third-party API calls** using non-Wix HTTP methods
|
|
18
|
+
|
|
19
|
+
**EXCEPTION**: SDK actions that you get from the AutoPatterns SDK (e.g., `sdk.getOptimisticActions()`, `sdk.getSchema()`) do NOT need error handling as they are already handled internally.
|
|
20
|
+
|
|
21
|
+
## Why Error Handling is Required
|
|
22
|
+
|
|
23
|
+
Custom data sources often make HTTP requests to Wix APIs and services. Without proper error handling:
|
|
24
|
+
|
|
25
|
+
- **Unhandled Promise Rejections**: HTTP failures can crash your application
|
|
26
|
+
- **Poor User Experience**: Users don't get meaningful error messages
|
|
27
|
+
- **Inconsistent Error Management**: Different parts of your app handle errors differently
|
|
28
|
+
- **Debugging Difficulties**: Hard to trace and diagnose API failures
|
|
29
|
+
|
|
30
|
+
## Using @wix/essentials errorHandler
|
|
31
|
+
|
|
32
|
+
The recommended approach is to use the `errorHandler` from `@wix/essentials` package, which provides consistent error handling patterns across Wix applications.
|
|
33
|
+
|
|
34
|
+
### Installation
|
|
35
|
+
|
|
36
|
+
First, ensure `@wix/essentials` is installed in your project:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm install @wix/essentials
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Basic Error Handling Pattern
|
|
43
|
+
|
|
44
|
+
Wrap Wix HTTP requests in your custom data source actions with `errorHandler.withErrorHandler`:
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
import { errorHandler } from '@wix/essentials';
|
|
48
|
+
|
|
49
|
+
// In your custom data source actions
|
|
50
|
+
actions: {
|
|
51
|
+
get: async (entityId: string) => {
|
|
52
|
+
return errorHandler.withErrorHandler(
|
|
53
|
+
async () => {
|
|
54
|
+
const response = await httpClient.request(
|
|
55
|
+
getDummyEntity({ dummyEntityId: entityId })
|
|
56
|
+
);
|
|
57
|
+
return response.data.dummyEntity;
|
|
58
|
+
},
|
|
59
|
+
{}
|
|
60
|
+
);
|
|
61
|
+
},
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Examples of HTTP Requests That Need Error Handling
|
|
66
|
+
|
|
67
|
+
**httpClient from @wix/essentials:**
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
return errorHandler.withErrorHandler(async () => {
|
|
71
|
+
const response = await httpClient.request(
|
|
72
|
+
getDummyEntity({ dummyEntityId: entityId })
|
|
73
|
+
);
|
|
74
|
+
return response.data.dummyEntity;
|
|
75
|
+
}, {});
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Wix APIs (wix/data, wix/stores):**
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
return errorHandler.withErrorHandler(async () => {
|
|
82
|
+
return await items.get(collectionId, entityId);
|
|
83
|
+
}, {});
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**httpClient.fetchWithAuth() calls:**
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
return errorHandler.withErrorHandler(async () => {
|
|
90
|
+
const response = await httpClient.fetchWithAuth("/api/data");
|
|
91
|
+
return await response.json();
|
|
92
|
+
}, {});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Examples of HTTP Requests That Do NOT Need Error Handling
|
|
96
|
+
|
|
97
|
+
**External API calls (using fetch, axios, etc.):**
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
// ✅ CORRECT - No error handling needed for external APIs
|
|
101
|
+
const response = await fetch("https://api.example.com/data");
|
|
102
|
+
return await response.json();
|
|
103
|
+
|
|
104
|
+
// ✅ CORRECT - No error handling needed for axios
|
|
105
|
+
const response = await axios.get("https://api.example.com/data");
|
|
106
|
+
return response.data;
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**Third-party HTTP libraries:**
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
// ✅ CORRECT - No error handling needed for third-party HTTP clients
|
|
113
|
+
const response = await someThirdPartyHttpClient.get("/data");
|
|
114
|
+
return response.data;
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Integration with AutoPatterns Error Handling
|
|
118
|
+
|
|
119
|
+
The error handling in your custom data source integrates seamlessly with AutoPatterns' built-in error handling:
|
|
120
|
+
|
|
121
|
+
1. **User-Friendly Messages**: Errors are displayed to users in a consistent format
|
|
122
|
+
2. **Retry Mechanisms**: Users can retry failed operations
|
|
123
|
+
3. **Loading States**: Proper loading states during HTTP requests
|
|
124
|
+
4. **Error Boundaries**: Errors are caught and handled gracefully
|
|
125
|
+
|
|
126
|
+
## Validation Checklist
|
|
127
|
+
|
|
128
|
+
Before deploying your custom data source, ensure:
|
|
129
|
+
|
|
130
|
+
✅ **httpClient from @wix/essentials** is wrapped with `errorHandler.withErrorHandler`
|
|
131
|
+
✅ **Wix APIs (wix/data, wix/stores, etc)** are wrapped with `errorHandler.withErrorHandler`
|
|
132
|
+
✅ **httpClient.fetchWithAuth()** calls are wrapped with `errorHandler.withErrorHandler`
|
|
133
|
+
✅ **External API calls are NOT wrapped** with errorHandler (e.g., fetch(), axios, third-party HTTP clients)
|
|
134
|
+
✅ **SDK actions are used directly** without error handling (e.g., `sdk.getOptimisticActions()`, `sdk.getSchema()`)
|
|
135
|
+
✅ **@wix/essentials** is installed as a dependency
|
package/dist/docs/index.md
CHANGED
|
@@ -74,6 +74,10 @@ This index maps user requests to the appropriate section IDs for fetching releva
|
|
|
74
74
|
**Topics**: FQDN-based custom data sources, Wix Business API integration, schema mapping, custom data source implementation
|
|
75
75
|
**Keywords**: FQDN, Wix Business API, custom data source, schema mapping, client library, field type mapping, custom implementation, entityTypeSource custom, Business API integration, schema extraction
|
|
76
76
|
|
|
77
|
+
### ID: `error_handling`
|
|
78
|
+
**Topics**: HTTP request error handling, errorHandler usage, custom data source error management, API error handling
|
|
79
|
+
**Keywords**: error handling, HTTP errors, API errors, errorHandler, @wix/essentials, custom data source errors, error management, promise rejections, user experience, error messages
|
|
80
|
+
|
|
77
81
|
---
|
|
78
82
|
|
|
79
83
|
## Recipe Section IDs (Step-by-Step Guides)
|
|
@@ -16,19 +16,25 @@ export interface SchemaConfig {
|
|
|
16
16
|
update: (updatedEntity: any) => Promise<any>;
|
|
17
17
|
delete: (entityId: string) => Promise<any>;
|
|
18
18
|
bulkDelete: (entityIds: string[]) => Promise<any>;
|
|
19
|
+
// The return shape depends on pagination mode (see AppConfig.collection.paginationMode)
|
|
20
|
+
// - Cursor mode: { items, cursor, total? }
|
|
21
|
+
// - Offset mode (default): { items, hasNext, total? }
|
|
19
22
|
find: (
|
|
20
23
|
query: Query,
|
|
21
24
|
options?: {
|
|
22
25
|
searchableFieldIds?: string[];
|
|
23
26
|
filterFieldMapping?: Record<string, { fieldId: string }>;
|
|
24
27
|
},
|
|
25
|
-
) => Promise<
|
|
28
|
+
) => Promise<
|
|
29
|
+
| { items: any[]; cursor?: string | null; total?: number | null }
|
|
30
|
+
| { items: any[]; hasNext?: boolean; total?: number | null }
|
|
31
|
+
>;
|
|
26
32
|
};
|
|
27
33
|
}
|
|
28
34
|
|
|
29
35
|
export interface Query {
|
|
30
36
|
limit: number; // Maximum number of items to return per request (controls page size)
|
|
31
|
-
offset
|
|
37
|
+
offset?: number; // Number of items to skip from the beginning (for pagination)
|
|
32
38
|
page: number; // Current page number (1-based, works with limit for pagination)
|
|
33
39
|
search?: string; // Text search query applied to searchable fields
|
|
34
40
|
cursor?: string | null; // Cursor-based pagination token (alternative to offset-based pagination)
|
|
@@ -127,7 +133,9 @@ export type Field = ReferenceField | NonReferenceField;
|
|
|
127
133
|
- `query`: Query object with pagination, filtering, sorting, and search criteria (see Query Interface section)
|
|
128
134
|
- `options.searchableFieldIds`: Array of field IDs that support text search
|
|
129
135
|
- `options.filterFieldMapping`: Maps filter IDs to actual field IDs for complex filtering
|
|
130
|
-
- Returns
|
|
136
|
+
- Returns (depends on pagination mode):
|
|
137
|
+
- Cursor mode: `{ items: any[]; cursor?: string | null; total?: number | null }`
|
|
138
|
+
- Offset mode (default): `{ items: any[]; hasNext?: boolean; total?: number | null }`
|
|
131
139
|
|
|
132
140
|
### Field Type Information
|
|
133
141
|
|
|
@@ -114,6 +114,7 @@ Follow the complete custom data source implementation guide in the "Custom Overr
|
|
|
114
114
|
1. **Import the client library** identified in Step 2
|
|
115
115
|
2. **Use the field mappings** from Step 3 in your SchemaConfig
|
|
116
116
|
3. **⚠️ CRITICAL: DO NOT IMPLEMENT THE ACTIONS** - Instead, add guidance comments explaining how to use the imported client library for each CRUD operation, then throw an "unimplemented exception" error
|
|
117
|
+
4. **⚠️ CRITICAL: Add Error Handling** - When implementing the actions, you MUST wrap all HTTP requests with proper error handling using `errorHandler` from `@wix/essentials` (see "Error Handling for HTTP Requests" section)
|
|
117
118
|
|
|
118
119
|
**Important**: The schema actions should contain helpful comments but NOT actual implementations. Each action should throw an error indicating it's unimplemented and needs to be implemented by the user.
|
|
119
120
|
|
|
@@ -123,6 +124,8 @@ Create your custom data source with the hook pattern:
|
|
|
123
124
|
|
|
124
125
|
In `components/customDataSources/myCustomDataSource.ts`:
|
|
125
126
|
```typescript
|
|
127
|
+
import { errorHandler } from '@wix/essentials';
|
|
128
|
+
|
|
126
129
|
export const myCustomDataSource = async (collectionId: string, context: any) => {
|
|
127
130
|
return {
|
|
128
131
|
id: 'myCustomCollection',
|
|
@@ -134,37 +137,76 @@ export const myCustomDataSource = async (collectionId: string, context: any) =>
|
|
|
134
137
|
actions: {
|
|
135
138
|
get: async (entityId: string) => {
|
|
136
139
|
// TODO: Implement using your FQDN client library
|
|
137
|
-
// Example:
|
|
140
|
+
// Example:
|
|
141
|
+
// return errorHandler.withErrorHandler(
|
|
142
|
+
// async () => {
|
|
143
|
+
// return yourFQDNClient.getEntity(entityId);
|
|
144
|
+
// },
|
|
145
|
+
// {}
|
|
146
|
+
// );
|
|
138
147
|
// Remember to map the response fields from snake_case to camelCase
|
|
139
148
|
throw new Error('get action not implemented - user must implement this method');
|
|
140
149
|
},
|
|
141
150
|
create: async (newEntity: any) => {
|
|
142
151
|
// TODO: Implement using your FQDN client library
|
|
143
|
-
// Example:
|
|
152
|
+
// Example:
|
|
153
|
+
// return errorHandler.withErrorHandler(
|
|
154
|
+
// async () => {
|
|
155
|
+
// return yourFQDNClient.createEntity(newEntity);
|
|
156
|
+
// },
|
|
157
|
+
// {}
|
|
158
|
+
// );
|
|
144
159
|
// Remember to map the request fields from camelCase to snake_case
|
|
145
160
|
throw new Error('create action not implemented - user must implement this method');
|
|
146
161
|
},
|
|
147
162
|
update: async (updatedEntity: any) => {
|
|
148
163
|
// TODO: Implement using your FQDN client library
|
|
149
|
-
// Example:
|
|
164
|
+
// Example:
|
|
165
|
+
// return errorHandler.withErrorHandler(
|
|
166
|
+
// async () => {
|
|
167
|
+
// return yourFQDNClient.updateEntity(updatedEntity);
|
|
168
|
+
// },
|
|
169
|
+
// {}
|
|
170
|
+
// );
|
|
150
171
|
// Remember to map the request fields from camelCase to snake_case
|
|
151
172
|
throw new Error('update action not implemented - user must implement this method');
|
|
152
173
|
},
|
|
153
174
|
delete: async (entityId: string) => {
|
|
154
175
|
// TODO: Implement using your FQDN client library
|
|
155
|
-
// Example:
|
|
176
|
+
// Example:
|
|
177
|
+
// return errorHandler.withErrorHandler(
|
|
178
|
+
// async () => {
|
|
179
|
+
// return yourFQDNClient.deleteEntity(entityId);
|
|
180
|
+
// },
|
|
181
|
+
// {}
|
|
182
|
+
// );
|
|
156
183
|
throw new Error('delete action not implemented - user must implement this method');
|
|
157
184
|
},
|
|
158
185
|
bulkDelete: async (entityIds: string[]) => {
|
|
159
186
|
// TODO: Implement using your FQDN client library
|
|
160
|
-
// Example:
|
|
187
|
+
// Example:
|
|
188
|
+
// return errorHandler.withErrorHandler(
|
|
189
|
+
// async () => {
|
|
190
|
+
// return yourFQDNClient.bulkDeleteEntities(entityIds);
|
|
191
|
+
// },
|
|
192
|
+
// {}
|
|
193
|
+
// );
|
|
161
194
|
throw new Error('bulkDelete action not implemented - user must implement this method');
|
|
162
195
|
},
|
|
163
196
|
find: async (query: Query, options?: any) => {
|
|
164
197
|
// TODO: Implement using your FQDN client library
|
|
165
|
-
// Example:
|
|
198
|
+
// Example:
|
|
199
|
+
// return errorHandler.withErrorHandler(
|
|
200
|
+
// async () => {
|
|
201
|
+
// return yourFQDNClient.queryEntities(query, options);
|
|
202
|
+
// },
|
|
203
|
+
// {}
|
|
204
|
+
// );
|
|
166
205
|
// Remember to map the response fields from snake_case to camelCase
|
|
167
|
-
//
|
|
206
|
+
// IMPORTANT: Return shape depends on pagination mode.
|
|
207
|
+
// Detect by presence of query.cursor (cursor mode) vs. query.offset/page (offset mode):
|
|
208
|
+
// - Cursor mode: return { items, cursor, total? }
|
|
209
|
+
// - Offset mode (default): return { items, hasNext, total? }
|
|
168
210
|
throw new Error('find action not implemented - user must implement this method');
|
|
169
211
|
}
|
|
170
212
|
}
|
|
@@ -31,7 +31,7 @@ export async function fetchCmsData(collectionId, query, fields, options) {
|
|
|
31
31
|
if (referenceFieldIds.length > 0) {
|
|
32
32
|
dataQuery = dataQuery.include(...referenceFieldIds);
|
|
33
33
|
}
|
|
34
|
-
const res = await dataQuery.skip(query.offset).limit(query.limit).find({
|
|
34
|
+
const res = await dataQuery.skip(query.offset ?? 0).limit(query.limit).find({
|
|
35
35
|
returnTotalCount: true
|
|
36
36
|
});
|
|
37
37
|
return {
|