@la-main-verte/shared-types 1.0.83 → 1.0.86
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 +1 -1
- package/src/audience.d.ts +86 -0
- package/src/home.api.d.ts +262 -276
- package/src/index.ts +35 -34
- package/src/member.d.ts +126 -72
- package/src/plant.d.ts +12 -1
- package/src/users.api.d.ts +134 -136
package/package.json
CHANGED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audience targeting shared types
|
|
3
|
+
* -------------------------------
|
|
4
|
+
* An Audience is a reusable, named set of targeting criteria. Membership is
|
|
5
|
+
* precomputed into a join table, so these shapes describe the *definition* of
|
|
6
|
+
* an audience, not its resolved members.
|
|
7
|
+
*
|
|
8
|
+
* Criteria are heterogeneous and open-ended: each `type` has its own `params`.
|
|
9
|
+
* The canonical runtime validation lives in the zod discriminated union at
|
|
10
|
+
* `server/domains/audience/criterion.schema.ts`; keep these types in sync with it.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/** How an audience combines its criteria. */
|
|
14
|
+
export type AudienceCombinator = 'all' | 'any'
|
|
15
|
+
|
|
16
|
+
/** Member within `radiusKm` of a point. `label` is a human-readable origin (e.g. a city name). */
|
|
17
|
+
export interface GeoRadiusCriterion {
|
|
18
|
+
type: 'geo_radius'
|
|
19
|
+
params: {
|
|
20
|
+
latitude: number
|
|
21
|
+
longitude: number
|
|
22
|
+
radiusKm: number
|
|
23
|
+
label?: string
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Member whose `countryCode` matches (ISO 3166-1 alpha-2, e.g. "CA", "US", "FR").
|
|
29
|
+
* @see documentation/geographic-targeting.md
|
|
30
|
+
*/
|
|
31
|
+
export interface CountryCriterion {
|
|
32
|
+
type: 'country'
|
|
33
|
+
params: { countryCode: string }
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Member whose `provinceCode` matches (ISO 3166-2 subdivision code, e.g. "CA-QC", "US-CA", "FR-IDF").
|
|
38
|
+
* @see documentation/geographic-targeting.md
|
|
39
|
+
*/
|
|
40
|
+
export interface ProvinceCriterion {
|
|
41
|
+
type: 'province'
|
|
42
|
+
params: { provinceCode: string }
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Member whose `city` matches (case-insensitive). */
|
|
46
|
+
export interface CityCriterion {
|
|
47
|
+
type: 'city'
|
|
48
|
+
params: { cityName: string }
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** Member owns at least one GardenMap of the given category (e.g. "greenhouse"). */
|
|
52
|
+
export interface GardenMapCategoryCriterion {
|
|
53
|
+
type: 'garden_map_category'
|
|
54
|
+
params: { category: string }
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Behavioral: member who was active on at least `minDistinctDays` distinct
|
|
59
|
+
* calendar days (counted from SessionEvents) within the last `windowDays`.
|
|
60
|
+
* Time-relative — evaluated at recompute time, so the daily refresh cron keeps
|
|
61
|
+
* the trailing window honest.
|
|
62
|
+
*/
|
|
63
|
+
export interface ActivityDistinctDaysCriterion {
|
|
64
|
+
type: 'activity_distinct_days'
|
|
65
|
+
params: { minDistinctDays: number; windowDays: number }
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export type AudienceCriterion =
|
|
69
|
+
| GeoRadiusCriterion
|
|
70
|
+
| CountryCriterion
|
|
71
|
+
| ProvinceCriterion
|
|
72
|
+
| CityCriterion
|
|
73
|
+
| GardenMapCategoryCriterion
|
|
74
|
+
| ActivityDistinctDaysCriterion
|
|
75
|
+
|
|
76
|
+
export type AudienceCriterionType = AudienceCriterion['type']
|
|
77
|
+
|
|
78
|
+
export interface AudienceI {
|
|
79
|
+
id: number
|
|
80
|
+
name: string
|
|
81
|
+
description: string | null
|
|
82
|
+
combinator: AudienceCombinator
|
|
83
|
+
criteria: AudienceCriterion[]
|
|
84
|
+
createdAt: Date
|
|
85
|
+
updatedAt: Date
|
|
86
|
+
}
|
package/src/home.api.d.ts
CHANGED
|
@@ -1,276 +1,262 @@
|
|
|
1
|
-
import type { PlantI } from './plant'
|
|
2
|
-
import type { SelectionI } from './selection'
|
|
3
|
-
import type { TaskI } from './task'
|
|
4
|
-
|
|
5
|
-
export namespace HOME {
|
|
6
|
-
export type HeroCardMode = 'featuredSelection' | 'featuredPlant'
|
|
7
|
-
|
|
8
|
-
export type SectionComponentType =
|
|
9
|
-
| 'Header'
|
|
10
|
-
| 'HeroCards'
|
|
11
|
-
| 'PlantCarousel'
|
|
12
|
-
| 'HeroCardsCarousel'
|
|
13
|
-
| 'WideCardsCarousel'
|
|
14
|
-
| 'Weather'
|
|
15
|
-
| 'AdviceCarousel'
|
|
16
|
-
| 'OnboardingCard'
|
|
17
|
-
| 'UpcomingTasks'
|
|
18
|
-
|
|
19
|
-
export type CarouselComponentType = Extract<
|
|
20
|
-
SectionComponentType,
|
|
21
|
-
'PlantCarousel' | 'HeroCardsCarousel' | 'WideCardsCarousel'
|
|
22
|
-
>
|
|
23
|
-
|
|
24
|
-
export interface WeatherDayI {
|
|
25
|
-
date: string
|
|
26
|
-
minTempC: number
|
|
27
|
-
maxTempC: number
|
|
28
|
-
iconUrl: string | null
|
|
29
|
-
condition?: string | null
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export interface WeatherSectionI {
|
|
33
|
-
componentType: 'Weather'
|
|
34
|
-
title: string
|
|
35
|
-
subtitle?: string
|
|
36
|
-
locationName: string
|
|
37
|
-
timezone: string
|
|
38
|
-
days: WeatherDayI[]
|
|
39
|
-
lastUpdatedAt: string
|
|
40
|
-
dataSource: 'weatherapi'
|
|
41
|
-
backgroundColor?: string
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export interface HeaderSectionI {
|
|
45
|
-
componentType: 'Header'
|
|
46
|
-
title: string
|
|
47
|
-
subtitle: string
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export interface AdviceI {
|
|
51
|
-
id?: string | number
|
|
52
|
-
title: string
|
|
53
|
-
markdownContent: string
|
|
54
|
-
titleColor?: string
|
|
55
|
-
backgroundColor?: string
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export interface AdviceSectionI {
|
|
59
|
-
componentType: 'AdviceCarousel'
|
|
60
|
-
title?: string
|
|
61
|
-
subtitle?: string
|
|
62
|
-
advices: AdviceI[]
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export interface WideCardAuthorI {
|
|
66
|
-
name?: string | null
|
|
67
|
-
imageURL?: string | null
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export interface WideCardItemI {
|
|
71
|
-
id?: string | number
|
|
72
|
-
title?: string | null
|
|
73
|
-
text: string
|
|
74
|
-
badgeText?: string | null
|
|
75
|
-
thumbnailImageURL: string
|
|
76
|
-
author?: WideCardAuthorI | null
|
|
77
|
-
link?: string | null
|
|
78
|
-
metadata?: Record<string, unknown>
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export interface WideCardsCarouselSectionI {
|
|
82
|
-
componentType: 'WideCardsCarousel'
|
|
83
|
-
title: string
|
|
84
|
-
subtitle?: string
|
|
85
|
-
cards: WideCardItemI[]
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export interface HeroCardBlueprintI {
|
|
89
|
-
mode: HeroCardMode
|
|
90
|
-
title?: string | null
|
|
91
|
-
description?: string | null
|
|
92
|
-
backgroundColor?: string | null
|
|
93
|
-
backgroundImageUrl?: string | null
|
|
94
|
-
ctaLabel?: string | null
|
|
95
|
-
ctaRoute?: string | null
|
|
96
|
-
previewPlants?: PlantI[]
|
|
97
|
-
selection?: SelectionI | null
|
|
98
|
-
plant?: PlantI | null
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export interface HeroCardsSectionI {
|
|
102
|
-
componentType: 'HeroCards'
|
|
103
|
-
title?: string | null
|
|
104
|
-
subtitle?: string | null
|
|
105
|
-
cards: HeroCardBlueprintI[]
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export interface PlantCarouselSectionI {
|
|
109
|
-
componentType: 'PlantCarousel'
|
|
110
|
-
title: string
|
|
111
|
-
subtitle?: string
|
|
112
|
-
selection: SelectionI
|
|
113
|
-
displayRanking?: boolean
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
export interface HeroCardsCarouselSectionI {
|
|
117
|
-
componentType: 'HeroCardsCarousel'
|
|
118
|
-
selections: SelectionI[]
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export interface FamilyRecommendationI {
|
|
122
|
-
family: string
|
|
123
|
-
headline: string
|
|
124
|
-
plants: PlantI[]
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export interface FamilyExplorerSectionI {
|
|
128
|
-
componentType: 'FamilyExplorer'
|
|
129
|
-
title: string
|
|
130
|
-
subtitle?: string
|
|
131
|
-
families: FamilyRecommendationI[]
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
export interface OnboardingStepI {
|
|
135
|
-
id: string
|
|
136
|
-
title: string
|
|
137
|
-
description: string
|
|
138
|
-
isCompleted: boolean
|
|
139
|
-
ctaLink: string
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
export interface OnboardingCardSectionI {
|
|
143
|
-
componentType: 'OnboardingCard'
|
|
144
|
-
title: string
|
|
145
|
-
subtitle: string
|
|
146
|
-
steps: OnboardingStepI[]
|
|
147
|
-
completedStepsCount: number
|
|
148
|
-
totalStepsCount: number
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/** Minimal plant info for preview display (e.g. parent plant in grouped tasks) */
|
|
152
|
-
export interface TaskPlantPreviewI {
|
|
153
|
-
name: string
|
|
154
|
-
slug: string
|
|
155
|
-
imageURL?: string | null
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/** Plant info within a family group — includes the task ID specific to this plant */
|
|
159
|
-
export interface TaskFamilyPlantPreviewI extends TaskPlantPreviewI {
|
|
160
|
-
taskId: number
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/** Family group info when multiple plants share the same task */
|
|
164
|
-
export interface TaskFamilyGroupI {
|
|
165
|
-
familyName: string
|
|
166
|
-
plantsCount: number
|
|
167
|
-
plants: TaskFamilyPlantPreviewI[]
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
export interface UpcomingTaskI {
|
|
171
|
-
task: TaskI
|
|
172
|
-
/** PlantSelection id used by task list views to group tasks per planted item. */
|
|
173
|
-
plantSelectionId?: number
|
|
174
|
-
plantName: string
|
|
175
|
-
plantSlug: string
|
|
176
|
-
plantImageURL?: string | null
|
|
177
|
-
gardenName: string
|
|
178
|
-
gardenCategory: string
|
|
179
|
-
selectionSlug: string
|
|
180
|
-
/** If this task is grouped by family */
|
|
181
|
-
familyGroup?: TaskFamilyGroupI
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
export type TaskListView = 'current' | 'completed' | 'earlier'
|
|
185
|
-
|
|
186
|
-
export interface
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
|
251
|
-
|
|
252
|
-
|
|
|
253
|
-
|
|
|
254
|
-
|
|
|
255
|
-
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
export interface HeroCardItemI {
|
|
264
|
-
id?: string | null
|
|
265
|
-
mode: HeroCardMode
|
|
266
|
-
title?: string | null
|
|
267
|
-
description?: string | null
|
|
268
|
-
backgroundColor?: string | null
|
|
269
|
-
backgroundImageUrl?: string | null
|
|
270
|
-
previewPlants?: PlantI[]
|
|
271
|
-
ctaLabel?: string | null
|
|
272
|
-
selection?: SelectionI | null
|
|
273
|
-
plant?: PlantI | null
|
|
274
|
-
ctaRoute?: string | null
|
|
275
|
-
}
|
|
276
|
-
}
|
|
1
|
+
import type { PlantI } from './plant'
|
|
2
|
+
import type { SelectionI } from './selection'
|
|
3
|
+
import type { TaskI } from './task'
|
|
4
|
+
|
|
5
|
+
export namespace HOME {
|
|
6
|
+
export type HeroCardMode = 'featuredSelection' | 'featuredPlant'
|
|
7
|
+
|
|
8
|
+
export type SectionComponentType =
|
|
9
|
+
| 'Header'
|
|
10
|
+
| 'HeroCards'
|
|
11
|
+
| 'PlantCarousel'
|
|
12
|
+
| 'HeroCardsCarousel'
|
|
13
|
+
| 'WideCardsCarousel'
|
|
14
|
+
| 'Weather'
|
|
15
|
+
| 'AdviceCarousel'
|
|
16
|
+
| 'OnboardingCard'
|
|
17
|
+
| 'UpcomingTasks'
|
|
18
|
+
|
|
19
|
+
export type CarouselComponentType = Extract<
|
|
20
|
+
SectionComponentType,
|
|
21
|
+
'PlantCarousel' | 'HeroCardsCarousel' | 'WideCardsCarousel'
|
|
22
|
+
>
|
|
23
|
+
|
|
24
|
+
export interface WeatherDayI {
|
|
25
|
+
date: string
|
|
26
|
+
minTempC: number
|
|
27
|
+
maxTempC: number
|
|
28
|
+
iconUrl: string | null
|
|
29
|
+
condition?: string | null
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface WeatherSectionI {
|
|
33
|
+
componentType: 'Weather'
|
|
34
|
+
title: string
|
|
35
|
+
subtitle?: string
|
|
36
|
+
locationName: string
|
|
37
|
+
timezone: string
|
|
38
|
+
days: WeatherDayI[]
|
|
39
|
+
lastUpdatedAt: string
|
|
40
|
+
dataSource: 'weatherapi'
|
|
41
|
+
backgroundColor?: string
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface HeaderSectionI {
|
|
45
|
+
componentType: 'Header'
|
|
46
|
+
title: string
|
|
47
|
+
subtitle: string
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface AdviceI {
|
|
51
|
+
id?: string | number
|
|
52
|
+
title: string
|
|
53
|
+
markdownContent: string
|
|
54
|
+
titleColor?: string
|
|
55
|
+
backgroundColor?: string
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface AdviceSectionI {
|
|
59
|
+
componentType: 'AdviceCarousel'
|
|
60
|
+
title?: string
|
|
61
|
+
subtitle?: string
|
|
62
|
+
advices: AdviceI[]
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface WideCardAuthorI {
|
|
66
|
+
name?: string | null
|
|
67
|
+
imageURL?: string | null
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface WideCardItemI {
|
|
71
|
+
id?: string | number
|
|
72
|
+
title?: string | null
|
|
73
|
+
text: string
|
|
74
|
+
badgeText?: string | null
|
|
75
|
+
thumbnailImageURL: string
|
|
76
|
+
author?: WideCardAuthorI | null
|
|
77
|
+
link?: string | null
|
|
78
|
+
metadata?: Record<string, unknown>
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface WideCardsCarouselSectionI {
|
|
82
|
+
componentType: 'WideCardsCarousel'
|
|
83
|
+
title: string
|
|
84
|
+
subtitle?: string
|
|
85
|
+
cards: WideCardItemI[]
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export interface HeroCardBlueprintI {
|
|
89
|
+
mode: HeroCardMode
|
|
90
|
+
title?: string | null
|
|
91
|
+
description?: string | null
|
|
92
|
+
backgroundColor?: string | null
|
|
93
|
+
backgroundImageUrl?: string | null
|
|
94
|
+
ctaLabel?: string | null
|
|
95
|
+
ctaRoute?: string | null
|
|
96
|
+
previewPlants?: PlantI[]
|
|
97
|
+
selection?: SelectionI | null
|
|
98
|
+
plant?: PlantI | null
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface HeroCardsSectionI {
|
|
102
|
+
componentType: 'HeroCards'
|
|
103
|
+
title?: string | null
|
|
104
|
+
subtitle?: string | null
|
|
105
|
+
cards: HeroCardBlueprintI[]
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export interface PlantCarouselSectionI {
|
|
109
|
+
componentType: 'PlantCarousel'
|
|
110
|
+
title: string
|
|
111
|
+
subtitle?: string
|
|
112
|
+
selection: SelectionI
|
|
113
|
+
displayRanking?: boolean
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export interface HeroCardsCarouselSectionI {
|
|
117
|
+
componentType: 'HeroCardsCarousel'
|
|
118
|
+
selections: SelectionI[]
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export interface FamilyRecommendationI {
|
|
122
|
+
family: string
|
|
123
|
+
headline: string
|
|
124
|
+
plants: PlantI[]
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export interface FamilyExplorerSectionI {
|
|
128
|
+
componentType: 'FamilyExplorer'
|
|
129
|
+
title: string
|
|
130
|
+
subtitle?: string
|
|
131
|
+
families: FamilyRecommendationI[]
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export interface OnboardingStepI {
|
|
135
|
+
id: string
|
|
136
|
+
title: string
|
|
137
|
+
description: string
|
|
138
|
+
isCompleted: boolean
|
|
139
|
+
ctaLink: string
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export interface OnboardingCardSectionI {
|
|
143
|
+
componentType: 'OnboardingCard'
|
|
144
|
+
title: string
|
|
145
|
+
subtitle: string
|
|
146
|
+
steps: OnboardingStepI[]
|
|
147
|
+
completedStepsCount: number
|
|
148
|
+
totalStepsCount: number
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** Minimal plant info for preview display (e.g. parent plant in grouped tasks) */
|
|
152
|
+
export interface TaskPlantPreviewI {
|
|
153
|
+
name: string
|
|
154
|
+
slug: string
|
|
155
|
+
imageURL?: string | null
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/** Plant info within a family group — includes the task ID specific to this plant */
|
|
159
|
+
export interface TaskFamilyPlantPreviewI extends TaskPlantPreviewI {
|
|
160
|
+
taskId: number
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/** Family group info when multiple plants share the same task */
|
|
164
|
+
export interface TaskFamilyGroupI {
|
|
165
|
+
familyName: string
|
|
166
|
+
plantsCount: number
|
|
167
|
+
plants: TaskFamilyPlantPreviewI[]
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export interface UpcomingTaskI {
|
|
171
|
+
task: TaskI
|
|
172
|
+
/** PlantSelection id used by task list views to group tasks per planted item. */
|
|
173
|
+
plantSelectionId?: number
|
|
174
|
+
plantName: string
|
|
175
|
+
plantSlug: string
|
|
176
|
+
plantImageURL?: string | null
|
|
177
|
+
gardenName: string
|
|
178
|
+
gardenCategory: string
|
|
179
|
+
selectionSlug: string
|
|
180
|
+
/** If this task is grouped by family */
|
|
181
|
+
familyGroup?: TaskFamilyGroupI
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export type TaskListView = 'current' | 'completed' | 'earlier'
|
|
185
|
+
|
|
186
|
+
export interface UpcomingTaskAdviceI {
|
|
187
|
+
/** @deprecated Since 1.9.10, this field is always `''`. */
|
|
188
|
+
content: string
|
|
189
|
+
taskName: string
|
|
190
|
+
plantName: string
|
|
191
|
+
plantSlug: string
|
|
192
|
+
plantImageURL?: string | null
|
|
193
|
+
gardenName: string
|
|
194
|
+
gardenCategory: string
|
|
195
|
+
selectionSlug: string
|
|
196
|
+
task: TaskI
|
|
197
|
+
/** If this task is grouped by family */
|
|
198
|
+
familyGroup?: TaskFamilyGroupI
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export interface UpcomingTasksSectionI {
|
|
202
|
+
componentType: 'UpcomingTasks'
|
|
203
|
+
title: string
|
|
204
|
+
subtitle?: string
|
|
205
|
+
advices: UpcomingTaskAdviceI[]
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/** Preview plant for WhenToSeedWhat section */
|
|
209
|
+
export interface WhenToSeedWhatPlantPreviewI {
|
|
210
|
+
id: number
|
|
211
|
+
name: string
|
|
212
|
+
family?: string | null
|
|
213
|
+
slug: string
|
|
214
|
+
imageURL?: string | null
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/** A generic link card section with title, subtitle, URL, and optional preview images */
|
|
218
|
+
export interface LinkCardSectionI {
|
|
219
|
+
componentType: 'LinkCard'
|
|
220
|
+
title: string
|
|
221
|
+
subtitle?: string
|
|
222
|
+
url: string
|
|
223
|
+
previewPlants?: WhenToSeedWhatPlantPreviewI[]
|
|
224
|
+
backgroundColor?: string
|
|
225
|
+
/** Show a red badge indicator (replaces the plant preview stack when true) */
|
|
226
|
+
showBadge?: boolean
|
|
227
|
+
/** Optional badge count to display */
|
|
228
|
+
badgeCount?: number
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export type SectionI =
|
|
232
|
+
| HeaderSectionI
|
|
233
|
+
| HeroCardsSectionI
|
|
234
|
+
| PlantCarouselSectionI
|
|
235
|
+
| HeroCardsCarouselSectionI
|
|
236
|
+
| WideCardsCarouselSectionI
|
|
237
|
+
| WeatherSectionI
|
|
238
|
+
| AdviceSectionI
|
|
239
|
+
| OnboardingCardSectionI
|
|
240
|
+
| UpcomingTasksSectionI
|
|
241
|
+
| LinkCardSectionI
|
|
242
|
+
|
|
243
|
+
export interface Response {
|
|
244
|
+
sections: SectionI[]
|
|
245
|
+
weather?: WeatherSectionI
|
|
246
|
+
advice?: AdviceSectionI
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export interface HeroCardItemI {
|
|
250
|
+
id?: string | null
|
|
251
|
+
mode: HeroCardMode
|
|
252
|
+
title?: string | null
|
|
253
|
+
description?: string | null
|
|
254
|
+
backgroundColor?: string | null
|
|
255
|
+
backgroundImageUrl?: string | null
|
|
256
|
+
previewPlants?: PlantI[]
|
|
257
|
+
ctaLabel?: string | null
|
|
258
|
+
selection?: SelectionI | null
|
|
259
|
+
plant?: PlantI | null
|
|
260
|
+
ctaRoute?: string | null
|
|
261
|
+
}
|
|
262
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,34 +1,35 @@
|
|
|
1
|
-
export * from './member'
|
|
2
|
-
export * from './selection'
|
|
3
|
-
export * from './plantSelection'
|
|
4
|
-
export * from './plant'
|
|
5
|
-
export * from './task'
|
|
6
|
-
export * from './calendarView'
|
|
7
|
-
export * from './apiError'
|
|
8
|
-
export * from './gardenMap'
|
|
9
|
-
export * from './gardenOverview'
|
|
10
|
-
export * from './alert'
|
|
11
|
-
export * from './
|
|
12
|
-
export * from './
|
|
13
|
-
export * from './
|
|
14
|
-
export * from './
|
|
15
|
-
export * from './
|
|
16
|
-
export * from './
|
|
17
|
-
export * from './
|
|
18
|
-
export * from './
|
|
19
|
-
|
|
20
|
-
import * as
|
|
21
|
-
import * as
|
|
22
|
-
import * as
|
|
23
|
-
import * as
|
|
24
|
-
import * as
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
export import
|
|
30
|
-
export import
|
|
31
|
-
export import
|
|
32
|
-
export import
|
|
33
|
-
export import
|
|
34
|
-
|
|
1
|
+
export * from './member'
|
|
2
|
+
export * from './selection'
|
|
3
|
+
export * from './plantSelection'
|
|
4
|
+
export * from './plant'
|
|
5
|
+
export * from './task'
|
|
6
|
+
export * from './calendarView'
|
|
7
|
+
export * from './apiError'
|
|
8
|
+
export * from './gardenMap'
|
|
9
|
+
export * from './gardenOverview'
|
|
10
|
+
export * from './alert'
|
|
11
|
+
export * from './audience'
|
|
12
|
+
export * from './image'
|
|
13
|
+
export * from './note'
|
|
14
|
+
export * from './taggedItem'
|
|
15
|
+
export * from './fertilizer'
|
|
16
|
+
export * from './utmParams'
|
|
17
|
+
export * from './plantFilters'
|
|
18
|
+
export * from './taxonFamily'
|
|
19
|
+
export * from './rotationGroup'
|
|
20
|
+
import * as PlantsAPI from './plants.api'
|
|
21
|
+
import * as UsersAPI from './users.api'
|
|
22
|
+
import * as SessionsAPI from './sessions.api'
|
|
23
|
+
import * as HomeAPI from './home.api'
|
|
24
|
+
import * as PagesAPI from './pages.api'
|
|
25
|
+
import * as PaymentsAPI from './payments.api'
|
|
26
|
+
|
|
27
|
+
// Allow access to the API namespaces without conflicts
|
|
28
|
+
export namespace API {
|
|
29
|
+
export import PLANTS = PlantsAPI
|
|
30
|
+
export import USERS = UsersAPI
|
|
31
|
+
export import SESSIONS = SessionsAPI
|
|
32
|
+
export import HOME = HomeAPI
|
|
33
|
+
export import PAGES = PagesAPI
|
|
34
|
+
export import PAYMENTS = PaymentsAPI
|
|
35
|
+
}
|
package/src/member.d.ts
CHANGED
|
@@ -1,72 +1,126 @@
|
|
|
1
|
-
import type { NoteI } from './note'
|
|
2
|
-
import type { SelectionI } from './selection'
|
|
3
|
-
|
|
4
|
-
export interface MemberI {
|
|
5
|
-
id: number
|
|
6
|
-
email: string
|
|
7
|
-
firstName: string
|
|
8
|
-
lastName: string
|
|
9
|
-
/** Virtual field to get the user's full name */
|
|
10
|
-
fullName?: string | null
|
|
11
|
-
city?: string
|
|
12
|
-
hardinessZoneName?: string
|
|
13
|
-
createdAt: Date
|
|
14
|
-
updatedAt: Date
|
|
15
|
-
lastFreezingDate?: Date
|
|
16
|
-
firstFreezingDate?: Date
|
|
17
|
-
/**
|
|
18
|
-
* Number of unread Crisp messages
|
|
19
|
-
*/
|
|
20
|
-
unreadMessagesCount?: number
|
|
21
|
-
notes?: NoteI[]
|
|
22
|
-
selections?: SelectionI[]
|
|
23
|
-
userActivities?: UserActivityI[]
|
|
24
|
-
/**
|
|
25
|
-
* hasAnActiveSubscription is a VIRTUAL FIELD used to check if the user has an active subscription
|
|
26
|
-
*/
|
|
27
|
-
hasAnActiveSubscription?: boolean
|
|
28
|
-
/**
|
|
29
|
-
* Acts as a one-way not identifiable token.
|
|
30
|
-
* Crisp uses this token to identify the user conversation
|
|
31
|
-
*/
|
|
32
|
-
userToken: string
|
|
33
|
-
/**
|
|
34
|
-
* HMAC signature used by Crisp identity verification.
|
|
35
|
-
* Signed on the backend from the user email.
|
|
36
|
-
*/
|
|
37
|
-
crispUserEmailSignature?: string
|
|
38
|
-
/**
|
|
39
|
-
* neverAddedATask <=> Has the use ever open the task form?
|
|
40
|
-
* Yes it is misleading, ticket is open to change it.
|
|
41
|
-
* It was too intense to force the user to add a task.
|
|
42
|
-
*/
|
|
43
|
-
neverAddedATask?: boolean
|
|
44
|
-
neverAddedAPlant?: boolean
|
|
45
|
-
neverAddedANote?: boolean
|
|
46
|
-
neverTriedSpacingSection?: boolean
|
|
47
|
-
neverTriedAiAgent?: boolean
|
|
48
|
-
neverDeletedAPlant?: boolean
|
|
49
|
-
neverDeletedATask?: boolean
|
|
50
|
-
neverEditedATask?: boolean
|
|
51
|
-
finishedOnboarding: boolean
|
|
52
|
-
hasDownloadedNativeApp?: boolean
|
|
53
|
-
unitSystem: 'imperial' | 'metric'
|
|
54
|
-
gardenZoneTimelessPreference?: boolean
|
|
55
|
-
subscriptionEndDate?: Date
|
|
56
|
-
/**
|
|
57
|
-
* Last fertilizer ID chosen by the user.
|
|
58
|
-
* Used as the default fertilizer for new garden zones.
|
|
59
|
-
*/
|
|
60
|
-
lastFertilizerIdChosen?: number
|
|
61
|
-
/**
|
|
62
|
-
* Virtual field to get the app badge count
|
|
63
|
-
* ----------------------------------------
|
|
64
|
-
* For now, it's just the number of unread messages.
|
|
65
|
-
*/
|
|
66
|
-
badgeCount?: number
|
|
67
|
-
/**
|
|
68
|
-
* Number of unread alerts, cached version of unread alerts (the table) count
|
|
69
|
-
*/
|
|
70
|
-
unreadAlertsCount?: number
|
|
71
|
-
isAdmin: boolean
|
|
72
|
-
}
|
|
1
|
+
import type { NoteI } from './note'
|
|
2
|
+
import type { SelectionI } from './selection'
|
|
3
|
+
|
|
4
|
+
export interface MemberI {
|
|
5
|
+
id: number
|
|
6
|
+
email: string
|
|
7
|
+
firstName: string
|
|
8
|
+
lastName: string
|
|
9
|
+
/** Virtual field to get the user's full name */
|
|
10
|
+
fullName?: string | null
|
|
11
|
+
city?: string
|
|
12
|
+
hardinessZoneName?: string
|
|
13
|
+
createdAt: Date
|
|
14
|
+
updatedAt: Date
|
|
15
|
+
lastFreezingDate?: Date
|
|
16
|
+
firstFreezingDate?: Date
|
|
17
|
+
/**
|
|
18
|
+
* Number of unread Crisp messages
|
|
19
|
+
*/
|
|
20
|
+
unreadMessagesCount?: number
|
|
21
|
+
notes?: NoteI[]
|
|
22
|
+
selections?: SelectionI[]
|
|
23
|
+
userActivities?: UserActivityI[]
|
|
24
|
+
/**
|
|
25
|
+
* hasAnActiveSubscription is a VIRTUAL FIELD used to check if the user has an active subscription
|
|
26
|
+
*/
|
|
27
|
+
hasAnActiveSubscription?: boolean
|
|
28
|
+
/**
|
|
29
|
+
* Acts as a one-way not identifiable token.
|
|
30
|
+
* Crisp uses this token to identify the user conversation
|
|
31
|
+
*/
|
|
32
|
+
userToken: string
|
|
33
|
+
/**
|
|
34
|
+
* HMAC signature used by Crisp identity verification.
|
|
35
|
+
* Signed on the backend from the user email.
|
|
36
|
+
*/
|
|
37
|
+
crispUserEmailSignature?: string
|
|
38
|
+
/**
|
|
39
|
+
* neverAddedATask <=> Has the use ever open the task form?
|
|
40
|
+
* Yes it is misleading, ticket is open to change it.
|
|
41
|
+
* It was too intense to force the user to add a task.
|
|
42
|
+
*/
|
|
43
|
+
neverAddedATask?: boolean
|
|
44
|
+
neverAddedAPlant?: boolean
|
|
45
|
+
neverAddedANote?: boolean
|
|
46
|
+
neverTriedSpacingSection?: boolean
|
|
47
|
+
neverTriedAiAgent?: boolean
|
|
48
|
+
neverDeletedAPlant?: boolean
|
|
49
|
+
neverDeletedATask?: boolean
|
|
50
|
+
neverEditedATask?: boolean
|
|
51
|
+
finishedOnboarding: boolean
|
|
52
|
+
hasDownloadedNativeApp?: boolean
|
|
53
|
+
unitSystem: 'imperial' | 'metric'
|
|
54
|
+
gardenZoneTimelessPreference?: boolean
|
|
55
|
+
subscriptionEndDate?: Date
|
|
56
|
+
/**
|
|
57
|
+
* Last fertilizer ID chosen by the user.
|
|
58
|
+
* Used as the default fertilizer for new garden zones.
|
|
59
|
+
*/
|
|
60
|
+
lastFertilizerIdChosen?: number
|
|
61
|
+
/**
|
|
62
|
+
* Virtual field to get the app badge count
|
|
63
|
+
* ----------------------------------------
|
|
64
|
+
* For now, it's just the number of unread messages.
|
|
65
|
+
*/
|
|
66
|
+
badgeCount?: number
|
|
67
|
+
/**
|
|
68
|
+
* Number of unread alerts, cached version of unread alerts (the table) count
|
|
69
|
+
*/
|
|
70
|
+
unreadAlertsCount?: number
|
|
71
|
+
isAdmin: boolean
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* PrivateMemberI
|
|
76
|
+
* --------------
|
|
77
|
+
* The data a member is allowed to see about *themselves* — the shape
|
|
78
|
+
* returned to the front-end by GET/POST /users. (A future `PublicMemberI`
|
|
79
|
+
* will model the much smaller set of fields shown to other members.)
|
|
80
|
+
*
|
|
81
|
+
* Unlike `MemberI` (the full domain model), this is a deliberate
|
|
82
|
+
* allow-list of only the fields the client actually consumes. It exists
|
|
83
|
+
* to prevent leaking sensitive or internal Member columns: anything not
|
|
84
|
+
* listed here is never serialized to the client. Keep this in sync with
|
|
85
|
+
* `privateMember.presenter.ts` on the backend.
|
|
86
|
+
*/
|
|
87
|
+
export interface PrivateMemberI {
|
|
88
|
+
id: number
|
|
89
|
+
email: string
|
|
90
|
+
city?: string
|
|
91
|
+
unitSystem: 'imperial' | 'metric'
|
|
92
|
+
gardenZoneTimelessPreference?: boolean
|
|
93
|
+
firstFreezingDate?: Date
|
|
94
|
+
lastFreezingDate?: Date
|
|
95
|
+
subscriptionEndDate?: Date
|
|
96
|
+
hasAnActiveSubscription?: boolean
|
|
97
|
+
hasDownloadedNativeApp?: boolean
|
|
98
|
+
isAdmin: boolean
|
|
99
|
+
/**
|
|
100
|
+
* App badge count (currently unread messages + unread alerts).
|
|
101
|
+
*/
|
|
102
|
+
badgeCount?: number
|
|
103
|
+
/**
|
|
104
|
+
* One-way Crisp identification token. Not personally identifiable.
|
|
105
|
+
*/
|
|
106
|
+
userToken: string
|
|
107
|
+
/**
|
|
108
|
+
* HMAC signature used by Crisp identity verification.
|
|
109
|
+
*/
|
|
110
|
+
crispUserEmailSignature?: string
|
|
111
|
+
unreadMessagesCount?: number
|
|
112
|
+
unreadAlertsCount?: number
|
|
113
|
+
neverAddedANote?: boolean
|
|
114
|
+
neverAddedAPlant?: boolean
|
|
115
|
+
neverDeletedAPlant?: boolean
|
|
116
|
+
neverEditedATask?: boolean
|
|
117
|
+
neverTriedAiAgent?: boolean
|
|
118
|
+
neverTriedSpacingSection?: boolean
|
|
119
|
+
/**
|
|
120
|
+
* True when the member belongs to the "very active" audience (~14 days of
|
|
121
|
+
* distinct activity). Only present when GET /users is called with the
|
|
122
|
+
* `requestAppStoreReview` scope; the app uses it to trigger a one-time
|
|
123
|
+
* in-app store-review prompt.
|
|
124
|
+
*/
|
|
125
|
+
requestAppStoreReview?: boolean
|
|
126
|
+
}
|
package/src/plant.d.ts
CHANGED
|
@@ -21,7 +21,18 @@ export type PlantFilterValueI = string | string[] | number | boolean | RangeFilt
|
|
|
21
21
|
* Used in JSONB field and as query parameters
|
|
22
22
|
* Supports multiple value types for different filter types
|
|
23
23
|
*/
|
|
24
|
-
|
|
24
|
+
/**
|
|
25
|
+
* A group of related attribute values, used for nested attribute objects.
|
|
26
|
+
* Ex: { growth: { type: 'déterminée' }}
|
|
27
|
+
*/
|
|
28
|
+
export type PlantAttributeGroupI = Record<string, PlantFilterValueI>
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Plant attributes for filtering
|
|
32
|
+
* Used in JSONB field and as query parameters
|
|
33
|
+
* Supports flat values and one level of nested groups.
|
|
34
|
+
*/
|
|
35
|
+
export type PlantAttributesI = Record<string, PlantFilterValueI | PlantAttributeGroupI>
|
|
25
36
|
|
|
26
37
|
export interface PlantI {
|
|
27
38
|
id: number
|
package/src/users.api.d.ts
CHANGED
|
@@ -1,136 +1,134 @@
|
|
|
1
|
-
import type { DeviceDataI } from './device.d'
|
|
2
|
-
import type {
|
|
3
|
-
import type { SelectionI } from './selection.d'
|
|
4
|
-
import type { PlantI } from './plant.d'
|
|
5
|
-
|
|
6
|
-
interface RequestHeaders {
|
|
7
|
-
'x-session-token': string
|
|
8
|
-
'x-native-app-version'?: string
|
|
9
|
-
'x-application-type'?: 'react-native' | 'web'
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export namespace USERS {
|
|
13
|
-
export namespace GET {
|
|
14
|
-
export interface Request {
|
|
15
|
-
headers: RequestHeaders
|
|
16
|
-
params: {
|
|
17
|
-
scopes: ('unreadNotificationsCount' | '
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
export type Response =
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
|
91
|
-
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
}
|
|
1
|
+
import type { DeviceDataI } from './device.d'
|
|
2
|
+
import type { PrivateMemberI } from './member.d'
|
|
3
|
+
import type { SelectionI } from './selection.d'
|
|
4
|
+
import type { PlantI } from './plant.d'
|
|
5
|
+
|
|
6
|
+
interface RequestHeaders {
|
|
7
|
+
'x-session-token': string
|
|
8
|
+
'x-native-app-version'?: string
|
|
9
|
+
'x-application-type'?: 'react-native' | 'web'
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export namespace USERS {
|
|
13
|
+
export namespace GET {
|
|
14
|
+
export interface Request {
|
|
15
|
+
headers: RequestHeaders
|
|
16
|
+
params: {
|
|
17
|
+
scopes: ('unreadNotificationsCount' | 'requestAppStoreReview')[]
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export type Response = PrivateMemberI
|
|
21
|
+
}
|
|
22
|
+
export namespace DEVICES {
|
|
23
|
+
export interface Request {
|
|
24
|
+
headers: RequestHeaders
|
|
25
|
+
body: {
|
|
26
|
+
/** @see DeviceDataI */
|
|
27
|
+
userAgent?: DeviceDataI['userAgent']
|
|
28
|
+
platform?: DeviceDataI['platform']
|
|
29
|
+
version?: DeviceDataI['version']
|
|
30
|
+
model?: DeviceDataI['model']
|
|
31
|
+
name?: DeviceDataI['name']
|
|
32
|
+
appVersion?: DeviceDataI['appVersion']
|
|
33
|
+
pushKey?: DeviceDataI['pushKey']
|
|
34
|
+
apnsToken?: DeviceDataI['apnsToken']
|
|
35
|
+
fcmToken?: DeviceDataI['fcmToken']
|
|
36
|
+
webPushEndpoint?: DeviceDataI['webPushEndpoint']
|
|
37
|
+
webPushP256dh?: DeviceDataI['webPushP256dh']
|
|
38
|
+
webPushAuth?: DeviceDataI['webPushAuth']
|
|
39
|
+
webPushSubscription?: DeviceDataI['webPushSubscription']
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export type Response = DeviceDataI
|
|
43
|
+
}
|
|
44
|
+
export namespace RECOMMENDATIONS {
|
|
45
|
+
export type ComponentType = 'PlantCarousel' | 'SelectionCarousel' | 'HeroCardsCarousel' | 'YourSelection'
|
|
46
|
+
|
|
47
|
+
interface BaseRecommendation {
|
|
48
|
+
id: string
|
|
49
|
+
componentType: ComponentType
|
|
50
|
+
title?: string
|
|
51
|
+
subtitle?: string
|
|
52
|
+
cardsVisible?: number
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface PlantCarouselRecommendation extends BaseRecommendation {
|
|
56
|
+
componentType: 'PlantCarousel'
|
|
57
|
+
selection: SelectionI & { Plants?: PlantI[] }
|
|
58
|
+
displayRanking?: boolean
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface SelectionCarouselRecommendation extends BaseRecommendation {
|
|
62
|
+
componentType: 'SelectionCarousel'
|
|
63
|
+
selections: SelectionI[]
|
|
64
|
+
displayRanking?: boolean
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface HeroCardsCarouselRecommendation extends BaseRecommendation {
|
|
68
|
+
componentType: 'HeroCardsCarousel'
|
|
69
|
+
selections: SelectionI[]
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface YourSelectionRecommendation extends BaseRecommendation {
|
|
73
|
+
componentType: 'YourSelection'
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface ThemedRecommendationI {
|
|
77
|
+
id: string
|
|
78
|
+
label: string
|
|
79
|
+
icon: string
|
|
80
|
+
title?: string
|
|
81
|
+
subtitle?: string
|
|
82
|
+
selections: SelectionI[]
|
|
83
|
+
cardsVisible?: number
|
|
84
|
+
displayRanking?: boolean
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export type RecommendationI =
|
|
88
|
+
| PlantCarouselRecommendation
|
|
89
|
+
| SelectionCarouselRecommendation
|
|
90
|
+
| HeroCardsCarouselRecommendation
|
|
91
|
+
| YourSelectionRecommendation
|
|
92
|
+
|
|
93
|
+
export interface Request {
|
|
94
|
+
headers: RequestHeaders
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface Response {
|
|
98
|
+
recommendations: RecommendationI[]
|
|
99
|
+
themedRecommendations: ThemedRecommendationI[]
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
export namespace UPDATE {
|
|
103
|
+
export interface Request {
|
|
104
|
+
headers: RequestHeaders
|
|
105
|
+
body: {
|
|
106
|
+
city?: string
|
|
107
|
+
lastFreezingDate?: string | Date
|
|
108
|
+
firstFreezingDate?: string | Date
|
|
109
|
+
moveDatesRequested?: boolean
|
|
110
|
+
lastFertilizerIdChosen?: number
|
|
111
|
+
lastOrganicMatterPercentage?: number
|
|
112
|
+
unitSystem?: 'imperial' | 'metric'
|
|
113
|
+
gardenZoneTimelessPreference?: boolean
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
export type Response = PrivateMemberI
|
|
117
|
+
}
|
|
118
|
+
export namespace GIFT_CARDS {
|
|
119
|
+
export namespace REDEEM {
|
|
120
|
+
export interface Request {
|
|
121
|
+
headers: RequestHeaders
|
|
122
|
+
body: {
|
|
123
|
+
code: string
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
export interface Response {
|
|
127
|
+
success: boolean
|
|
128
|
+
message?: string
|
|
129
|
+
error?: string
|
|
130
|
+
error_message?: string
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|