@universityofmaryland/web-feeds-library 1.3.0-beta.0 → 1.3.0-beta.1
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/academic.js +4 -4
- package/dist/academic.js.map +1 -1
- package/dist/events.js +10 -10
- package/dist/events.js.map +1 -1
- package/dist/experts.js +8 -8
- package/dist/experts.js.map +1 -1
- package/dist/factory/core/createBaseFeed.d.ts.map +1 -1
- package/dist/factory/core/createBaseFeed.js +19 -17
- package/dist/factory/core/createBaseFeed.js.map +1 -1
- package/dist/factory/core/types.d.ts +1 -0
- package/dist/factory/core/types.d.ts.map +1 -1
- package/dist/factory/helpers/displayHandler.js +29 -47
- package/dist/factory/helpers/displayHandler.js.map +1 -1
- package/dist/factory/helpers/feedHelpers.js +3 -3
- package/dist/factory/helpers/feedHelpers.js.map +1 -1
- package/dist/factory/helpers/fetchHandler.js +16 -33
- package/dist/factory/helpers/fetchHandler.js.map +1 -1
- package/dist/feeds/academic/index.d.ts +1 -1
- package/dist/feeds/academic/index.d.ts.map +1 -1
- package/dist/feeds/academic/slider.d.ts +1 -2
- package/dist/feeds/academic/slider.d.ts.map +1 -1
- package/dist/feeds/academic/slider.js +7 -6
- package/dist/feeds/academic/slider.js.map +1 -1
- package/dist/feeds/events/grid.d.ts +1 -2
- package/dist/feeds/events/grid.d.ts.map +1 -1
- package/dist/feeds/events/grid.js +22 -21
- package/dist/feeds/events/grid.js.map +1 -1
- package/dist/feeds/events/grouped.d.ts +1 -2
- package/dist/feeds/events/grouped.d.ts.map +1 -1
- package/dist/feeds/events/grouped.js +62 -78
- package/dist/feeds/events/grouped.js.map +1 -1
- package/dist/feeds/events/index.d.ts +4 -4
- package/dist/feeds/events/index.d.ts.map +1 -1
- package/dist/feeds/events/list.d.ts +1 -2
- package/dist/feeds/events/list.d.ts.map +1 -1
- package/dist/feeds/events/list.js +22 -21
- package/dist/feeds/events/list.js.map +1 -1
- package/dist/feeds/events/slider.d.ts +1 -2
- package/dist/feeds/events/slider.d.ts.map +1 -1
- package/dist/feeds/events/slider.js +7 -6
- package/dist/feeds/events/slider.js.map +1 -1
- package/dist/feeds/experts/_types.d.ts +2 -1
- package/dist/feeds/experts/_types.d.ts.map +1 -1
- package/dist/feeds/experts/bio.d.ts +1 -2
- package/dist/feeds/experts/bio.d.ts.map +1 -1
- package/dist/feeds/experts/bio.js +32 -31
- package/dist/feeds/experts/bio.js.map +1 -1
- package/dist/feeds/experts/grid.d.ts +1 -2
- package/dist/feeds/experts/grid.d.ts.map +1 -1
- package/dist/feeds/experts/grid.js +24 -23
- package/dist/feeds/experts/grid.js.map +1 -1
- package/dist/feeds/experts/index.d.ts +3 -3
- package/dist/feeds/experts/index.d.ts.map +1 -1
- package/dist/feeds/experts/list.d.ts +1 -2
- package/dist/feeds/experts/list.d.ts.map +1 -1
- package/dist/feeds/experts/list.js +23 -22
- package/dist/feeds/experts/list.js.map +1 -1
- package/dist/feeds/news/featured.d.ts +1 -2
- package/dist/feeds/news/featured.d.ts.map +1 -1
- package/dist/feeds/news/featured.js +56 -55
- package/dist/feeds/news/featured.js.map +1 -1
- package/dist/feeds/news/grid.d.ts +1 -2
- package/dist/feeds/news/grid.d.ts.map +1 -1
- package/dist/feeds/news/grid.js +24 -23
- package/dist/feeds/news/grid.js.map +1 -1
- package/dist/feeds/news/index.d.ts +3 -3
- package/dist/feeds/news/index.d.ts.map +1 -1
- package/dist/feeds/news/list.d.ts +1 -2
- package/dist/feeds/news/list.d.ts.map +1 -1
- package/dist/feeds/news/list.js +23 -22
- package/dist/feeds/news/list.js.map +1 -1
- package/dist/helpers/events/index.js +4 -4
- package/dist/helpers/events/index.js.map +1 -1
- package/dist/helpers/grouping/events.js +10 -10
- package/dist/helpers/grouping/events.js.map +1 -1
- package/dist/helpers/styles/shadow.js +5 -22
- package/dist/helpers/styles/shadow.js.map +1 -1
- package/dist/index.js +10 -10
- package/dist/index.js.map +1 -1
- package/dist/news.js +8 -8
- package/dist/news.js.map +1 -1
- package/dist/states/_types.d.ts +0 -24
- package/dist/states/_types.d.ts.map +1 -1
- package/dist/states/_types.js +3 -3
- package/dist/states/_types.js.map +1 -1
- package/dist/states/announcer.d.ts +1 -3
- package/dist/states/announcer.d.ts.map +1 -1
- package/dist/states/announcer.js +5 -5
- package/dist/states/announcer.js.map +1 -1
- package/dist/states/empty.d.ts +0 -2
- package/dist/states/empty.d.ts.map +1 -1
- package/dist/states/empty.js +15 -32
- package/dist/states/empty.js.map +1 -1
- package/dist/states/index.d.ts +4 -8
- package/dist/states/index.d.ts.map +1 -1
- package/dist/states/loading.d.ts +1 -3
- package/dist/states/loading.d.ts.map +1 -1
- package/dist/states/loading.js +16 -16
- package/dist/states/loading.js.map +1 -1
- package/dist/states/pagination.d.ts +1 -3
- package/dist/states/pagination.d.ts.map +1 -1
- package/dist/states/pagination.js +11 -28
- package/dist/states/pagination.js.map +1 -1
- package/dist/strategies/display/events.js +13 -13
- package/dist/strategies/display/events.js.map +1 -1
- package/dist/strategies/display/experts.js +23 -23
- package/dist/strategies/display/experts.js.map +1 -1
- package/dist/strategies/display/news.js +13 -13
- package/dist/strategies/display/news.js.map +1 -1
- package/dist/strategies/fetch/academic.js +3 -3
- package/dist/strategies/fetch/academic.js.map +1 -1
- package/dist/strategies/fetch/events.js +13 -13
- package/dist/strategies/fetch/events.js.map +1 -1
- package/dist/strategies/fetch/experts.d.ts +1 -1
- package/dist/strategies/fetch/experts.d.ts.map +1 -1
- package/dist/strategies/fetch/experts.js +13 -8
- package/dist/strategies/fetch/experts.js.map +1 -1
- package/dist/strategies/fetch/graphql.d.ts.map +1 -1
- package/dist/strategies/fetch/graphql.js +11 -7
- package/dist/strategies/fetch/graphql.js.map +1 -1
- package/dist/strategies/fetch/news.js +6 -6
- package/dist/strategies/fetch/news.js.map +1 -1
- package/dist/strategies/layout/grid.js +11 -11
- package/dist/strategies/layout/grid.js.map +1 -1
- package/dist/widgets/index.d.ts +1 -1
- package/dist/widgets/index.d.ts.map +1 -1
- package/dist/widgets/slider.d.ts +1 -2
- package/dist/widgets/slider.d.ts.map +1 -1
- package/dist/widgets/slider.js +19 -35
- package/dist/widgets/slider.js.map +1 -1
- package/package.json +15 -14
- package/dist/academic.mjs +0 -5
- package/dist/academic.mjs.map +0 -1
- package/dist/events.mjs +0 -11
- package/dist/events.mjs.map +0 -1
- package/dist/experts.mjs +0 -9
- package/dist/experts.mjs.map +0 -1
- package/dist/factory/core/createBaseFeed.mjs +0 -114
- package/dist/factory/core/createBaseFeed.mjs.map +0 -1
- package/dist/factory/helpers/displayHandler.mjs +0 -169
- package/dist/factory/helpers/displayHandler.mjs.map +0 -1
- package/dist/factory/helpers/feedHelpers.mjs +0 -32
- package/dist/factory/helpers/feedHelpers.mjs.map +0 -1
- package/dist/factory/helpers/fetchHandler.mjs +0 -123
- package/dist/factory/helpers/fetchHandler.mjs.map +0 -1
- package/dist/feeds/academic/slider.mjs +0 -11
- package/dist/feeds/academic/slider.mjs.map +0 -1
- package/dist/feeds/events/grid.mjs +0 -32
- package/dist/feeds/events/grid.mjs.map +0 -1
- package/dist/feeds/events/grouped.mjs +0 -337
- package/dist/feeds/events/grouped.mjs.map +0 -1
- package/dist/feeds/events/list.mjs +0 -33
- package/dist/feeds/events/list.mjs.map +0 -1
- package/dist/feeds/events/slider.mjs +0 -11
- package/dist/feeds/events/slider.mjs.map +0 -1
- package/dist/feeds/experts/bio.mjs +0 -147
- package/dist/feeds/experts/bio.mjs.map +0 -1
- package/dist/feeds/experts/grid.mjs +0 -37
- package/dist/feeds/experts/grid.mjs.map +0 -1
- package/dist/feeds/experts/list.mjs +0 -26
- package/dist/feeds/experts/list.mjs.map +0 -1
- package/dist/feeds/news/featured.mjs +0 -379
- package/dist/feeds/news/featured.mjs.map +0 -1
- package/dist/feeds/news/grid.mjs +0 -37
- package/dist/feeds/news/grid.mjs.map +0 -1
- package/dist/feeds/news/list.mjs +0 -34
- package/dist/feeds/news/list.mjs.map +0 -1
- package/dist/helpers/events/index.mjs +0 -21
- package/dist/helpers/events/index.mjs.map +0 -1
- package/dist/helpers/grouping/events.mjs +0 -147
- package/dist/helpers/grouping/events.mjs.map +0 -1
- package/dist/helpers/styles/shadow.mjs +0 -16
- package/dist/helpers/styles/shadow.mjs.map +0 -1
- package/dist/index.mjs +0 -11
- package/dist/index.mjs.map +0 -1
- package/dist/news.mjs +0 -9
- package/dist/news.mjs.map +0 -1
- package/dist/states/_types.mjs +0 -12
- package/dist/states/_types.mjs.map +0 -1
- package/dist/states/announcer.mjs +0 -62
- package/dist/states/announcer.mjs.map +0 -1
- package/dist/states/empty.mjs +0 -104
- package/dist/states/empty.mjs.map +0 -1
- package/dist/states/loading.mjs +0 -155
- package/dist/states/loading.mjs.map +0 -1
- package/dist/states/pagination.mjs +0 -102
- package/dist/states/pagination.mjs.map +0 -1
- package/dist/strategies/display/events.mjs +0 -60
- package/dist/strategies/display/events.mjs.map +0 -1
- package/dist/strategies/display/experts.mjs +0 -266
- package/dist/strategies/display/experts.mjs.map +0 -1
- package/dist/strategies/display/news.mjs +0 -58
- package/dist/strategies/display/news.mjs.map +0 -1
- package/dist/strategies/fetch/academic.mjs +0 -30
- package/dist/strategies/fetch/academic.mjs.map +0 -1
- package/dist/strategies/fetch/events.mjs +0 -223
- package/dist/strategies/fetch/events.mjs.map +0 -1
- package/dist/strategies/fetch/experts.mjs +0 -189
- package/dist/strategies/fetch/experts.mjs.map +0 -1
- package/dist/strategies/fetch/graphql.mjs +0 -100
- package/dist/strategies/fetch/graphql.mjs.map +0 -1
- package/dist/strategies/fetch/news.mjs +0 -95
- package/dist/strategies/fetch/news.mjs.map +0 -1
- package/dist/strategies/layout/grid.mjs +0 -36
- package/dist/strategies/layout/grid.mjs.map +0 -1
- package/dist/widgets/slider.mjs +0 -87
- package/dist/widgets/slider.mjs.map +0 -1
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
import { createGraphQLFetchStrategy } from "./graphql.mjs";
|
|
2
|
-
import { fetchGraphQL } from "@universityofmaryland/web-utilities-library/network";
|
|
3
|
-
const CALENDARS = ["communications", "submission"];
|
|
4
|
-
function generateFragments() {
|
|
5
|
-
return CALENDARS.map(
|
|
6
|
-
(cal) => `
|
|
7
|
-
fragment EventBasicFields_${cal} on ${cal}_Event {
|
|
8
|
-
id
|
|
9
|
-
title
|
|
10
|
-
url
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
fragment EventDateFields_${cal} on ${cal}_Event {
|
|
14
|
-
startDayOfWeek: startDate @formatDateTime(format: "D")
|
|
15
|
-
startMonth: startDate @formatDateTime(format: "M")
|
|
16
|
-
startDay: startDate @formatDateTime(format: "d")
|
|
17
|
-
startStamp: startDate @formatDateTime(format: "Y-m-d")
|
|
18
|
-
startTime: startDate @formatDateTime(format: "g:ia")
|
|
19
|
-
endDayOfWeek: endDate @formatDateTime(format: "D")
|
|
20
|
-
endMonth: endDate @formatDateTime(format: "M")
|
|
21
|
-
endDay: endDate @formatDateTime(format: "d")
|
|
22
|
-
endTime: endDate @formatDateTime(format: "g:ia")
|
|
23
|
-
allDay
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
fragment EventContentFields_${cal} on ${cal}_Event {
|
|
27
|
-
summary: commonRichTextTwo
|
|
28
|
-
image: commonAssetHeroImageSingle {
|
|
29
|
-
url
|
|
30
|
-
altText: commonPlainTextTwo
|
|
31
|
-
}
|
|
32
|
-
location: categoriesCampusBuildingSingle {
|
|
33
|
-
title
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
fragment EventCategoryFields_${cal} on ${cal}_Event {
|
|
38
|
-
categories: categoriesEventAudienceMultiple {
|
|
39
|
-
id
|
|
40
|
-
title
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
`
|
|
44
|
-
).join("\n");
|
|
45
|
-
}
|
|
46
|
-
function generateInlineSpreads() {
|
|
47
|
-
return CALENDARS.map(
|
|
48
|
-
(cal) => `
|
|
49
|
-
... on ${cal}_Event {
|
|
50
|
-
...EventBasicFields_${cal}
|
|
51
|
-
...EventDateFields_${cal}
|
|
52
|
-
...EventContentFields_${cal}
|
|
53
|
-
...EventCategoryFields_${cal}
|
|
54
|
-
}
|
|
55
|
-
`
|
|
56
|
-
).join("\n");
|
|
57
|
-
}
|
|
58
|
-
function generateSliderSpreads() {
|
|
59
|
-
return CALENDARS.map(
|
|
60
|
-
(cal) => `
|
|
61
|
-
... on ${cal}_Event {
|
|
62
|
-
...EventSliderFields_${cal}
|
|
63
|
-
}
|
|
64
|
-
`
|
|
65
|
-
).join("\n");
|
|
66
|
-
}
|
|
67
|
-
function generateSliderFragments() {
|
|
68
|
-
return CALENDARS.map(
|
|
69
|
-
(cal) => `
|
|
70
|
-
fragment EventSliderFields_${cal} on ${cal}_Event {
|
|
71
|
-
title
|
|
72
|
-
url
|
|
73
|
-
startMonth: startDate @formatDateTime(format: "M")
|
|
74
|
-
startDay: startDate @formatDateTime(format: "d")
|
|
75
|
-
endMonth: endDate @formatDateTime(format: "M")
|
|
76
|
-
endDay: endDate @formatDateTime(format: "d")
|
|
77
|
-
}
|
|
78
|
-
`
|
|
79
|
-
).join("\n");
|
|
80
|
-
}
|
|
81
|
-
const buildEventsCountQuery = (dateFilter = "startsAfterOrAt") => `
|
|
82
|
-
query getEventsCount($startDate: String!, $related: [QueryArgument]) {
|
|
83
|
-
count: solspace_calendar {
|
|
84
|
-
events(relatedTo: $related, loadOccurrences: true, ${dateFilter}: $startDate) {
|
|
85
|
-
... on communications_Event {
|
|
86
|
-
id
|
|
87
|
-
}
|
|
88
|
-
... on submission_Event {
|
|
89
|
-
id
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
`;
|
|
95
|
-
const buildEventsQuery = (dateFilter = "startsAfterOrAt") => `
|
|
96
|
-
query getEvents($startDate: String!, $related: [QueryArgument], $limit: Int, $offset: Int) {
|
|
97
|
-
entries: solspace_calendar {
|
|
98
|
-
events(
|
|
99
|
-
relatedTo: $related
|
|
100
|
-
loadOccurrences: true
|
|
101
|
-
${dateFilter}: $startDate
|
|
102
|
-
limit: $limit
|
|
103
|
-
offset: $offset
|
|
104
|
-
) {
|
|
105
|
-
${generateInlineSpreads()}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
${generateFragments()}
|
|
110
|
-
`;
|
|
111
|
-
const EVENTS_COUNT_QUERY = buildEventsCountQuery();
|
|
112
|
-
const EVENTS_QUERY = buildEventsQuery();
|
|
113
|
-
const CATEGORY_NAMES_QUERY = `
|
|
114
|
-
query getCategoryNames($ids: [QueryArgument]!) {
|
|
115
|
-
categories(id: $ids) {
|
|
116
|
-
id
|
|
117
|
-
title
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
`;
|
|
121
|
-
const EVENTS_SLIDER_QUERY = `
|
|
122
|
-
query getEvents($startDate: String!, $related: [QueryArgument]) {
|
|
123
|
-
entries: solspace_calendar {
|
|
124
|
-
events(
|
|
125
|
-
relatedTo: $related
|
|
126
|
-
loadOccurrences: true
|
|
127
|
-
startsAfterOrAt: $startDate
|
|
128
|
-
limit: 12
|
|
129
|
-
) {
|
|
130
|
-
${generateSliderSpreads()}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
${generateSliderFragments()}
|
|
135
|
-
`;
|
|
136
|
-
const baseFetchStrategy = createGraphQLFetchStrategy({
|
|
137
|
-
endpoint: "https://calendar.umd.edu/graphql",
|
|
138
|
-
queries: {
|
|
139
|
-
entries: EVENTS_QUERY,
|
|
140
|
-
count: EVENTS_COUNT_QUERY
|
|
141
|
-
},
|
|
142
|
-
transformResponse: (data) => {
|
|
143
|
-
if (!data || !data.data || !data.data.entries) {
|
|
144
|
-
return null;
|
|
145
|
-
}
|
|
146
|
-
return data.data.entries.events || null;
|
|
147
|
-
},
|
|
148
|
-
transformCount: (data) => {
|
|
149
|
-
if (!data || !data.data || !data.data.count) {
|
|
150
|
-
return 0;
|
|
151
|
-
}
|
|
152
|
-
return data.data.count.events?.length || 0;
|
|
153
|
-
},
|
|
154
|
-
composeVariables: (baseVariables) => {
|
|
155
|
-
const { categories, ...rest } = baseVariables;
|
|
156
|
-
return {
|
|
157
|
-
...rest,
|
|
158
|
-
related: categories,
|
|
159
|
-
startDate: (/* @__PURE__ */ new Date()).toDateString()
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
});
|
|
163
|
-
async function fetchCategoryNames(categoryIds, token) {
|
|
164
|
-
try {
|
|
165
|
-
const response = await fetchGraphQL({
|
|
166
|
-
url: "https://calendar.umd.edu/graphql",
|
|
167
|
-
query: CATEGORY_NAMES_QUERY,
|
|
168
|
-
token: token || "",
|
|
169
|
-
variables: { ids: categoryIds }
|
|
170
|
-
});
|
|
171
|
-
if (!response || !response.data || !response.data.categories) {
|
|
172
|
-
return null;
|
|
173
|
-
}
|
|
174
|
-
return response.data.categories.map((category) => category.title);
|
|
175
|
-
} catch (error) {
|
|
176
|
-
console.error("Fetch category names error:", error);
|
|
177
|
-
return null;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
const eventsFetchStrategy = {
|
|
181
|
-
...baseFetchStrategy,
|
|
182
|
-
fetchCategoryNames
|
|
183
|
-
};
|
|
184
|
-
const baseFetchStrategyRange = createGraphQLFetchStrategy({
|
|
185
|
-
endpoint: "https://calendar.umd.edu/graphql",
|
|
186
|
-
queries: {
|
|
187
|
-
entries: buildEventsQuery("rangeStart"),
|
|
188
|
-
count: buildEventsCountQuery("rangeStart")
|
|
189
|
-
},
|
|
190
|
-
transformResponse: (data) => {
|
|
191
|
-
if (!data || !data.data || !data.data.entries) {
|
|
192
|
-
return null;
|
|
193
|
-
}
|
|
194
|
-
return data.data.entries.events || null;
|
|
195
|
-
},
|
|
196
|
-
transformCount: (data) => {
|
|
197
|
-
if (!data || !data.data || !data.data.count) {
|
|
198
|
-
return 0;
|
|
199
|
-
}
|
|
200
|
-
return data.data.count.events?.length || 0;
|
|
201
|
-
},
|
|
202
|
-
composeVariables: (baseVariables) => {
|
|
203
|
-
const { categories, ...rest } = baseVariables;
|
|
204
|
-
return {
|
|
205
|
-
...rest,
|
|
206
|
-
related: categories,
|
|
207
|
-
startDate: (/* @__PURE__ */ new Date()).toDateString()
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
});
|
|
211
|
-
const eventsFetchStrategyRange = {
|
|
212
|
-
...baseFetchStrategyRange,
|
|
213
|
-
fetchCategoryNames
|
|
214
|
-
};
|
|
215
|
-
export {
|
|
216
|
-
CATEGORY_NAMES_QUERY,
|
|
217
|
-
EVENTS_COUNT_QUERY,
|
|
218
|
-
EVENTS_QUERY,
|
|
219
|
-
EVENTS_SLIDER_QUERY,
|
|
220
|
-
eventsFetchStrategy,
|
|
221
|
-
eventsFetchStrategyRange
|
|
222
|
-
};
|
|
223
|
-
//# sourceMappingURL=events.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"events.mjs","sources":["../../../source/strategies/fetch/events.ts"],"sourcesContent":["/**\n * Events Fetch Strategy\n *\n * Strategy for fetching event data from the UMD Calendar GraphQL API.\n *\n * @module strategies/fetch/events\n */\n\nimport { createGraphQLFetchStrategy } from './graphql';\nimport { EventEntry } from 'types/data';\nimport { fetchGraphQL } from '@universityofmaryland/web-utilities-library/network';\n\n/**\n * Calendar types available in the UMD Calendar system\n */\nconst CALENDARS = ['communications', 'submission'] as const;\n\n/**\n * Generate GraphQL fragments for all calendar types\n * Creates type-specific fragments to avoid interface limitations\n */\nfunction generateFragments() {\n return CALENDARS.map(\n (cal) => `\n fragment EventBasicFields_${cal} on ${cal}_Event {\n id\n title\n url\n }\n\n fragment EventDateFields_${cal} on ${cal}_Event {\n startDayOfWeek: startDate @formatDateTime(format: \"D\")\n startMonth: startDate @formatDateTime(format: \"M\")\n startDay: startDate @formatDateTime(format: \"d\")\n startStamp: startDate @formatDateTime(format: \"Y-m-d\")\n startTime: startDate @formatDateTime(format: \"g:ia\")\n endDayOfWeek: endDate @formatDateTime(format: \"D\")\n endMonth: endDate @formatDateTime(format: \"M\")\n endDay: endDate @formatDateTime(format: \"d\")\n endTime: endDate @formatDateTime(format: \"g:ia\")\n allDay\n }\n\n fragment EventContentFields_${cal} on ${cal}_Event {\n summary: commonRichTextTwo\n image: commonAssetHeroImageSingle {\n url\n altText: commonPlainTextTwo\n }\n location: categoriesCampusBuildingSingle {\n title\n }\n }\n\n fragment EventCategoryFields_${cal} on ${cal}_Event {\n categories: categoriesEventAudienceMultiple {\n id\n title\n }\n }\n `,\n ).join('\\n');\n}\n\n/**\n * Generate inline fragment spreads for all calendar types\n * Used in the main query to apply fragments to each calendar type\n */\nfunction generateInlineSpreads() {\n return CALENDARS.map(\n (cal) => `\n ... on ${cal}_Event {\n ...EventBasicFields_${cal}\n ...EventDateFields_${cal}\n ...EventContentFields_${cal}\n ...EventCategoryFields_${cal}\n }\n `,\n ).join('\\n');\n}\n\n/**\n * Generate inline fragment spreads for slider queries\n * Minimal fields for carousel displays\n */\nfunction generateSliderSpreads() {\n return CALENDARS.map(\n (cal) => `\n ... on ${cal}_Event {\n ...EventSliderFields_${cal}\n }\n `,\n ).join('\\n');\n}\n\n/**\n * Generate slider-specific fragments\n */\nfunction generateSliderFragments() {\n return CALENDARS.map(\n (cal) => `\n fragment EventSliderFields_${cal} on ${cal}_Event {\n title\n url\n startMonth: startDate @formatDateTime(format: \"M\")\n startDay: startDate @formatDateTime(format: \"d\")\n endMonth: endDate @formatDateTime(format: \"M\")\n endDay: endDate @formatDateTime(format: \"d\")\n }\n `,\n ).join('\\n');\n}\n\n/**\n * GraphQL queries for events\n */\nconst buildEventsCountQuery = (\n dateFilter: 'startsAfterOrAt' | 'rangeStart' = 'startsAfterOrAt',\n) => `\n query getEventsCount($startDate: String!, $related: [QueryArgument]) {\n count: solspace_calendar {\n events(relatedTo: $related, loadOccurrences: true, ${dateFilter}: $startDate) {\n ... on communications_Event {\n id\n }\n ... on submission_Event {\n id\n }\n }\n }\n }\n`;\n\nconst buildEventsQuery = (\n dateFilter: 'startsAfterOrAt' | 'rangeStart' = 'startsAfterOrAt',\n) => `\n query getEvents($startDate: String!, $related: [QueryArgument], $limit: Int, $offset: Int) {\n entries: solspace_calendar {\n events(\n relatedTo: $related\n loadOccurrences: true\n ${dateFilter}: $startDate\n limit: $limit\n offset: $offset\n ) {\n ${generateInlineSpreads()}\n }\n }\n }\n ${generateFragments()}\n`;\n\nexport const EVENTS_COUNT_QUERY = buildEventsCountQuery();\nexport const EVENTS_QUERY = buildEventsQuery();\n\n/**\n * Query for fetching category names by IDs\n * Queries the categories table directly\n */\nexport const CATEGORY_NAMES_QUERY = `\n query getCategoryNames($ids: [QueryArgument]!) {\n categories(id: $ids) {\n id\n title\n }\n }\n`;\n\n/**\n * Slider-specific query with minimal fields\n * Used by events slider for carousel displays\n */\nexport const EVENTS_SLIDER_QUERY = `\n query getEvents($startDate: String!, $related: [QueryArgument]) {\n entries: solspace_calendar {\n events(\n relatedTo: $related\n loadOccurrences: true\n startsAfterOrAt: $startDate\n limit: 12\n ) {\n ${generateSliderSpreads()}\n }\n }\n }\n ${generateSliderFragments()}\n`;\n\n/**\n * Events fetch strategy\n *\n * Fetches event data from the UMD Calendar GraphQL API.\n * Handles date filtering, category filtering, and pagination.\n *\n * @example\n * ```typescript\n * const feed = createBaseFeed({\n * token: 'my-token',\n * fetchStrategy: eventsFetchStrategy,\n * // ...\n * });\n * ```\n */\nconst baseFetchStrategy = createGraphQLFetchStrategy<EventEntry>({\n endpoint: 'https://calendar.umd.edu/graphql',\n\n queries: {\n entries: EVENTS_QUERY,\n count: EVENTS_COUNT_QUERY,\n },\n\n transformResponse: (data) => {\n if (!data || !data.data || !data.data.entries) {\n return null;\n }\n return data.data.entries.events || null;\n },\n\n transformCount: (data) => {\n if (!data || !data.data || !data.data.count) {\n return 0;\n }\n return data.data.count.events?.length || 0;\n },\n\n composeVariables: (baseVariables) => {\n const { categories, ...rest } = baseVariables;\n\n return {\n ...rest,\n related: categories,\n startDate: new Date().toDateString(),\n };\n },\n});\n\n/**\n * Fetch category names by their IDs\n */\nasync function fetchCategoryNames(\n categoryIds: string[],\n token?: string,\n): Promise<string[] | null> {\n try {\n const response = await fetchGraphQL({\n url: 'https://calendar.umd.edu/graphql',\n query: CATEGORY_NAMES_QUERY,\n token: token || '',\n variables: { ids: categoryIds },\n });\n\n if (!response || !response.data || !response.data.categories) {\n return null;\n }\n\n return response.data.categories.map((category: any) => category.title);\n } catch (error) {\n console.error('Fetch category names error:', error);\n return null;\n }\n}\n\nexport const eventsFetchStrategy = {\n ...baseFetchStrategy,\n fetchCategoryNames,\n};\n\n/**\n * Events fetch strategy for range queries\n *\n * Uses rangeStart filter instead of startsAfterOrAt.\n * Used for grouped event displays.\n */\nconst baseFetchStrategyRange = createGraphQLFetchStrategy<EventEntry>({\n endpoint: 'https://calendar.umd.edu/graphql',\n\n queries: {\n entries: buildEventsQuery('rangeStart'),\n count: buildEventsCountQuery('rangeStart'),\n },\n\n transformResponse: (data) => {\n if (!data || !data.data || !data.data.entries) {\n return null;\n }\n return data.data.entries.events || null;\n },\n\n transformCount: (data) => {\n if (!data || !data.data || !data.data.count) {\n return 0;\n }\n return data.data.count.events?.length || 0;\n },\n\n composeVariables: (baseVariables) => {\n const { categories, ...rest } = baseVariables;\n\n return {\n ...rest,\n related: categories,\n startDate: new Date().toDateString(),\n };\n },\n});\n\nexport const eventsFetchStrategyRange = {\n ...baseFetchStrategyRange,\n fetchCategoryNames,\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
import { createGraphQLFetchStrategy } from "./graphql.mjs";
|
|
2
|
-
const FRAGMENT_CATEGORIES_NATIVE_FIELDS = `
|
|
3
|
-
fragment CategoryFields on CategoryInterface {
|
|
4
|
-
title
|
|
5
|
-
url
|
|
6
|
-
id
|
|
7
|
-
}
|
|
8
|
-
`;
|
|
9
|
-
const FRAGMENT_ENTRIES_NATIVE_FIELDS = `
|
|
10
|
-
fragment EntriesNativeFields on EntryInterface {
|
|
11
|
-
id
|
|
12
|
-
uid
|
|
13
|
-
status
|
|
14
|
-
enabled
|
|
15
|
-
slug
|
|
16
|
-
title
|
|
17
|
-
type: typeHandle
|
|
18
|
-
postDate
|
|
19
|
-
expiryDate
|
|
20
|
-
dateUpdated
|
|
21
|
-
dateCreated
|
|
22
|
-
}
|
|
23
|
-
`;
|
|
24
|
-
const FRAGMENT_EXPERT_JOBS = `
|
|
25
|
-
fragment Jobs on expertsOrganizationJob_Entry {
|
|
26
|
-
id
|
|
27
|
-
url
|
|
28
|
-
title: expertsOrganizationJobTitle
|
|
29
|
-
roomNumber: expertsOrganizationJobRoomNumber
|
|
30
|
-
campusUnits: categoryCampusUnit {
|
|
31
|
-
title
|
|
32
|
-
... on campusUnits_Category {
|
|
33
|
-
link: externalLink {
|
|
34
|
-
url
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
`;
|
|
40
|
-
const FRAGMENT_EXPERT_NAME = `
|
|
41
|
-
fragment Name on expertsContent_Entry {
|
|
42
|
-
prefix: expertsNamePrefix
|
|
43
|
-
firstName: expertsNameFirst
|
|
44
|
-
middleName: expertsNameMiddle
|
|
45
|
-
lastName: expertsNameLast
|
|
46
|
-
suffix: expertsNameSuffix
|
|
47
|
-
pronouns: expertsNamePronouns
|
|
48
|
-
}
|
|
49
|
-
`;
|
|
50
|
-
const FRAGMENT_EXPERT_IMAGERY = `
|
|
51
|
-
fragment Imagery on expertsContent_Entry {
|
|
52
|
-
headshot: expertsImageHeadShot {
|
|
53
|
-
... on experts_Asset {
|
|
54
|
-
url
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
`;
|
|
59
|
-
const FRAGMENT_EXPERT_BIOGRAPHY = `
|
|
60
|
-
fragment Biography on expertsContent_Entry {
|
|
61
|
-
summary: expertsSummary {
|
|
62
|
-
html
|
|
63
|
-
}
|
|
64
|
-
bio: expertsBiography {
|
|
65
|
-
html
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
`;
|
|
69
|
-
const FRAGMENT_ENTRIES_ORGANIZATIONS = `
|
|
70
|
-
fragment Organizations on expertsOrganization_Entry {
|
|
71
|
-
id
|
|
72
|
-
title
|
|
73
|
-
url
|
|
74
|
-
jobs: expertsOrganizationJob {
|
|
75
|
-
...Jobs
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
`;
|
|
79
|
-
const FRAGMENT_EXPERT_CONTACT = `
|
|
80
|
-
fragment Contact on expertsContent_Entry {
|
|
81
|
-
email: expertsContactEmail
|
|
82
|
-
linkedin: expertsContactLinkedin
|
|
83
|
-
website: expertsContactWebsite
|
|
84
|
-
twitter: expertsContactTwitter
|
|
85
|
-
}
|
|
86
|
-
`;
|
|
87
|
-
const FRAGMENT_EXPERT_SKILLS = `
|
|
88
|
-
fragment Skills on expertsContent_Entry {
|
|
89
|
-
languages: expertsLanguages
|
|
90
|
-
mediaTrained: expertsMediaTrained
|
|
91
|
-
}
|
|
92
|
-
`;
|
|
93
|
-
const FRAGMENT_EXPERT_CONTENT = `
|
|
94
|
-
fragment Content on expertsContent_Entry {
|
|
95
|
-
...Name
|
|
96
|
-
...Imagery
|
|
97
|
-
...Biography
|
|
98
|
-
organizations: expertsOrganization {
|
|
99
|
-
...Organizations
|
|
100
|
-
}
|
|
101
|
-
...Contact
|
|
102
|
-
...Skills
|
|
103
|
-
}
|
|
104
|
-
`;
|
|
105
|
-
const FRAGMENT_EXPERT_CATEGORIES = `
|
|
106
|
-
fragment Categories on expertsContent_Entry {
|
|
107
|
-
areasOfExpertise: expertsCategoryAreaOfExpertise {
|
|
108
|
-
...CategoryFields
|
|
109
|
-
}
|
|
110
|
-
campusUnits: categoryCampusUnit {
|
|
111
|
-
...CategoryFields
|
|
112
|
-
}
|
|
113
|
-
tags: expertsCategoryTags {
|
|
114
|
-
...CategoryFields
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
`;
|
|
118
|
-
const EXPERTS_QUERY = `
|
|
119
|
-
query getExpertsContent($limit: Int, $offset: Int, $id: [QueryArgument], $relatedTo: [QueryArgument]) {
|
|
120
|
-
entryCount(
|
|
121
|
-
section: "experts"
|
|
122
|
-
limit: $limit
|
|
123
|
-
offset: $offset
|
|
124
|
-
type: "expertsContent"
|
|
125
|
-
id: $id
|
|
126
|
-
relatedTo: $relatedTo
|
|
127
|
-
)
|
|
128
|
-
entries(
|
|
129
|
-
section: "experts"
|
|
130
|
-
limit: $limit
|
|
131
|
-
offset: $offset
|
|
132
|
-
type: "expertsContent"
|
|
133
|
-
id: $id
|
|
134
|
-
relatedTo: $relatedTo
|
|
135
|
-
orderBy: "expertsNameLast"
|
|
136
|
-
) {
|
|
137
|
-
...EntriesNativeFields
|
|
138
|
-
... on expertsContent_Entry {
|
|
139
|
-
...Content
|
|
140
|
-
...Categories
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
${FRAGMENT_ENTRIES_NATIVE_FIELDS}
|
|
145
|
-
${FRAGMENT_CATEGORIES_NATIVE_FIELDS}
|
|
146
|
-
${FRAGMENT_EXPERT_CONTENT}
|
|
147
|
-
${FRAGMENT_EXPERT_CATEGORIES}
|
|
148
|
-
${FRAGMENT_EXPERT_NAME}
|
|
149
|
-
${FRAGMENT_EXPERT_IMAGERY}
|
|
150
|
-
${FRAGMENT_EXPERT_BIOGRAPHY}
|
|
151
|
-
${FRAGMENT_ENTRIES_ORGANIZATIONS}
|
|
152
|
-
${FRAGMENT_EXPERT_JOBS}
|
|
153
|
-
${FRAGMENT_EXPERT_CONTACT}
|
|
154
|
-
${FRAGMENT_EXPERT_SKILLS}
|
|
155
|
-
`;
|
|
156
|
-
const expertsFetchStrategy = createGraphQLFetchStrategy({
|
|
157
|
-
endpoint: "https://umd-api.production.servd.dev/graphql",
|
|
158
|
-
queries: {
|
|
159
|
-
entries: EXPERTS_QUERY
|
|
160
|
-
},
|
|
161
|
-
transformResponse: (data) => {
|
|
162
|
-
if (!data || !data.data || !data.data.entries) {
|
|
163
|
-
return null;
|
|
164
|
-
}
|
|
165
|
-
return data.data.entries || null;
|
|
166
|
-
},
|
|
167
|
-
transformCount: (data) => {
|
|
168
|
-
if (!data || !data.data) {
|
|
169
|
-
return 0;
|
|
170
|
-
}
|
|
171
|
-
return data.data.entryCount || 0;
|
|
172
|
-
},
|
|
173
|
-
composeVariables: (baseVariables) => {
|
|
174
|
-
const { categories, entriesToRemove, id, ...rest } = baseVariables;
|
|
175
|
-
const variables = { ...rest };
|
|
176
|
-
if (id) {
|
|
177
|
-
variables.id = Array.isArray(id) ? id : [id];
|
|
178
|
-
}
|
|
179
|
-
if (categories) {
|
|
180
|
-
variables.relatedTo = categories;
|
|
181
|
-
}
|
|
182
|
-
return variables;
|
|
183
|
-
}
|
|
184
|
-
});
|
|
185
|
-
export {
|
|
186
|
-
EXPERTS_QUERY,
|
|
187
|
-
expertsFetchStrategy
|
|
188
|
-
};
|
|
189
|
-
//# sourceMappingURL=experts.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"experts.mjs","sources":["../../../source/strategies/fetch/experts.ts"],"sourcesContent":["/**\n * Experts Fetch Strategy\n *\n * Strategy for fetching expert profile data from the UMD Experts GraphQL API.\n *\n * @module strategies/fetch/experts\n */\n\nimport { createGraphQLFetchStrategy } from './graphql';\nimport { ExpertEntry } from 'types/data';\n\n/**\n * GraphQL fragments for expert data\n */\nconst FRAGMENT_CATEGORIES_NATIVE_FIELDS = `\n fragment CategoryFields on CategoryInterface {\n title\n url\n id\n }\n`;\n\nconst FRAGMENT_ENTRIES_NATIVE_FIELDS = `\n fragment EntriesNativeFields on EntryInterface {\n id\n uid\n status\n enabled\n slug\n title\n type: typeHandle\n postDate\n expiryDate\n dateUpdated\n dateCreated\n }\n`;\n\nconst FRAGMENT_EXPERT_JOBS = `\n fragment Jobs on expertsOrganizationJob_Entry {\n id\n url\n title: expertsOrganizationJobTitle\n roomNumber: expertsOrganizationJobRoomNumber\n campusUnits: categoryCampusUnit {\n title\n ... on campusUnits_Category {\n link: externalLink {\n url\n }\n }\n }\n }\n`;\n\nconst FRAGMENT_EXPERT_NAME = `\n fragment Name on expertsContent_Entry {\n prefix: expertsNamePrefix\n firstName: expertsNameFirst\n middleName: expertsNameMiddle\n lastName: expertsNameLast\n suffix: expertsNameSuffix\n pronouns: expertsNamePronouns\n }\n`;\n\nconst FRAGMENT_EXPERT_IMAGERY = `\n fragment Imagery on expertsContent_Entry {\n headshot: expertsImageHeadShot {\n ... on experts_Asset {\n url\n }\n }\n }\n`;\n\nconst FRAGMENT_EXPERT_BIOGRAPHY = `\n fragment Biography on expertsContent_Entry {\n summary: expertsSummary {\n html\n }\n bio: expertsBiography {\n html\n }\n }\n`;\n\nconst FRAGMENT_ENTRIES_ORGANIZATIONS = `\n fragment Organizations on expertsOrganization_Entry {\n id\n title\n url\n jobs: expertsOrganizationJob {\n ...Jobs\n }\n }\n`;\n\nconst FRAGMENT_EXPERT_CONTACT = `\n fragment Contact on expertsContent_Entry {\n email: expertsContactEmail\n linkedin: expertsContactLinkedin\n website: expertsContactWebsite\n twitter: expertsContactTwitter\n }\n`;\n\nconst FRAGMENT_EXPERT_SKILLS = `\n fragment Skills on expertsContent_Entry {\n languages: expertsLanguages\n mediaTrained: expertsMediaTrained\n }\n`;\n\nconst FRAGMENT_EXPERT_CONTENT = `\n fragment Content on expertsContent_Entry {\n ...Name\n ...Imagery\n ...Biography\n organizations: expertsOrganization {\n ...Organizations\n }\n ...Contact\n ...Skills\n }\n`;\n\nconst FRAGMENT_EXPERT_CATEGORIES = `\n fragment Categories on expertsContent_Entry {\n areasOfExpertise: expertsCategoryAreaOfExpertise {\n ...CategoryFields\n }\n campusUnits: categoryCampusUnit {\n ...CategoryFields\n }\n tags: expertsCategoryTags {\n ...CategoryFields\n }\n }\n`;\n\n/**\n * GraphQL query for experts\n * Supports filtering by ID, relatedTo, or fetching all experts\n */\nexport const EXPERTS_QUERY = `\n query getExpertsContent($limit: Int, $offset: Int, $id: [QueryArgument], $relatedTo: [QueryArgument]) {\n entryCount(\n section: \"experts\"\n limit: $limit\n offset: $offset\n type: \"expertsContent\"\n id: $id\n relatedTo: $relatedTo\n )\n entries(\n section: \"experts\"\n limit: $limit\n offset: $offset\n type: \"expertsContent\"\n id: $id\n relatedTo: $relatedTo\n orderBy: \"expertsNameLast\"\n ) {\n ...EntriesNativeFields\n ... on expertsContent_Entry {\n ...Content\n ...Categories\n }\n }\n }\n ${FRAGMENT_ENTRIES_NATIVE_FIELDS}\n ${FRAGMENT_CATEGORIES_NATIVE_FIELDS}\n ${FRAGMENT_EXPERT_CONTENT}\n ${FRAGMENT_EXPERT_CATEGORIES}\n ${FRAGMENT_EXPERT_NAME}\n ${FRAGMENT_EXPERT_IMAGERY}\n ${FRAGMENT_EXPERT_BIOGRAPHY}\n ${FRAGMENT_ENTRIES_ORGANIZATIONS}\n ${FRAGMENT_EXPERT_JOBS}\n ${FRAGMENT_EXPERT_CONTACT}\n ${FRAGMENT_EXPERT_SKILLS}\n`;\n\n/**\n * Experts fetch strategy\n *\n * Fetches expert profile data from the UMD Experts GraphQL API.\n * Handles category filtering via relatedTo parameter, pagination,\n * and entry exclusion.\n *\n * @example\n * ```typescript\n * const feed = createBaseFeed({\n * token: 'my-token',\n * fetchStrategy: expertsFetchStrategy,\n * categories: ['computer-science', 'engineering'],\n * // ...\n * });\n * ```\n */\nexport const expertsFetchStrategy = createGraphQLFetchStrategy<ExpertEntry>({\n endpoint: 'https://umd-api.production.servd.dev/graphql',\n\n queries: {\n entries: EXPERTS_QUERY,\n },\n\n transformResponse: (data) => {\n if (!data || !data.data || !data.data.entries) {\n return null;\n }\n return data.data.entries || null;\n },\n\n transformCount: (data) => {\n if (!data || !data.data) {\n return 0;\n }\n return data.data.entryCount || 0;\n },\n\n composeVariables: (baseVariables) => {\n const { categories, entriesToRemove, id, ...rest } = baseVariables;\n\n const variables: any = { ...rest };\n\n // Handle fetching by ID (for single expert bio)\n if (id) {\n variables.id = Array.isArray(id) ? id : [id];\n }\n\n if (categories) {\n variables.relatedTo = categories;\n }\n\n return variables;\n },\n});\n"],"names":[],"mappings":";AAcA,MAAM,oCAAoC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQ1C,MAAM,iCAAiC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBvC,MAAM,uBAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiB7B,MAAM,uBAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAW7B,MAAM,0BAA0B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUhC,MAAM,4BAA4B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWlC,MAAM,iCAAiC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWvC,MAAM,0BAA0B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAShC,MAAM,yBAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAO/B,MAAM,0BAA0B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAahC,MAAM,6BAA6B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkB5B,MAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IA0BzB,8BAA8B;AAAA,IAC9B,iCAAiC;AAAA,IACjC,uBAAuB;AAAA,IACvB,0BAA0B;AAAA,IAC1B,oBAAoB;AAAA,IACpB,uBAAuB;AAAA,IACvB,yBAAyB;AAAA,IACzB,8BAA8B;AAAA,IAC9B,oBAAoB;AAAA,IACpB,uBAAuB;AAAA,IACvB,sBAAsB;AAAA;AAoBnB,MAAM,uBAAuB,2BAAwC;AAAA,EAC1E,UAAU;AAAA,EAEV,SAAS;AAAA,IACP,SAAS;AAAA,EAAA;AAAA,EAGX,mBAAmB,CAAC,SAAS;AAC3B,QAAI,CAAC,QAAQ,CAAC,KAAK,QAAQ,CAAC,KAAK,KAAK,SAAS;AAC7C,aAAO;AAAA,IACT;AACA,WAAO,KAAK,KAAK,WAAW;AAAA,EAC9B;AAAA,EAEA,gBAAgB,CAAC,SAAS;AACxB,QAAI,CAAC,QAAQ,CAAC,KAAK,MAAM;AACvB,aAAO;AAAA,IACT;AACA,WAAO,KAAK,KAAK,cAAc;AAAA,EACjC;AAAA,EAEA,kBAAkB,CAAC,kBAAkB;AACnC,UAAM,EAAE,YAAY,iBAAiB,IAAI,GAAG,SAAS;AAErD,UAAM,YAAiB,EAAE,GAAG,KAAA;AAG5B,QAAI,IAAI;AACN,gBAAU,KAAK,MAAM,QAAQ,EAAE,IAAI,KAAK,CAAC,EAAE;AAAA,IAC7C;AAEA,QAAI,YAAY;AACd,gBAAU,YAAY;AAAA,IACxB;AAEA,WAAO;AAAA,EACT;AACF,CAAC;"}
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import { fetchGraphQL } from "@universityofmaryland/web-utilities-library/network";
|
|
2
|
-
function createGraphQLFetchStrategy(config) {
|
|
3
|
-
const {
|
|
4
|
-
endpoint,
|
|
5
|
-
queries,
|
|
6
|
-
transformResponse,
|
|
7
|
-
transformCount,
|
|
8
|
-
composeVariables
|
|
9
|
-
} = config;
|
|
10
|
-
return {
|
|
11
|
-
/**
|
|
12
|
-
* Fetch the total count of entries
|
|
13
|
-
*/
|
|
14
|
-
fetchCount: async (variables) => {
|
|
15
|
-
try {
|
|
16
|
-
const query = queries.count || queries.entries;
|
|
17
|
-
const response = await fetchGraphQL({
|
|
18
|
-
url: endpoint,
|
|
19
|
-
query,
|
|
20
|
-
token: variables.token,
|
|
21
|
-
variables
|
|
22
|
-
});
|
|
23
|
-
if (!response || !response.data || response.message) {
|
|
24
|
-
if (response?.message) {
|
|
25
|
-
console.error(`GraphQL Error: ${response.message}`);
|
|
26
|
-
}
|
|
27
|
-
return null;
|
|
28
|
-
}
|
|
29
|
-
return transformCount(response);
|
|
30
|
-
} catch (error) {
|
|
31
|
-
console.error("Fetch count error:", error);
|
|
32
|
-
return null;
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
|
-
/**
|
|
36
|
-
* Fetch the actual entries
|
|
37
|
-
*/
|
|
38
|
-
fetchEntries: async (variables) => {
|
|
39
|
-
try {
|
|
40
|
-
const response = await fetchGraphQL({
|
|
41
|
-
url: endpoint,
|
|
42
|
-
query: queries.entries,
|
|
43
|
-
token: variables.token,
|
|
44
|
-
variables
|
|
45
|
-
});
|
|
46
|
-
if (!response || !response.data || response.message) {
|
|
47
|
-
if (response?.message) {
|
|
48
|
-
console.error(`GraphQL Error: ${response.message}`);
|
|
49
|
-
}
|
|
50
|
-
return null;
|
|
51
|
-
}
|
|
52
|
-
return transformResponse(response);
|
|
53
|
-
} catch (error) {
|
|
54
|
-
console.error("Fetch entries error:", error);
|
|
55
|
-
return null;
|
|
56
|
-
}
|
|
57
|
-
},
|
|
58
|
-
/**
|
|
59
|
-
* Compose API variables from feed props
|
|
60
|
-
*/
|
|
61
|
-
composeApiVariables: (props) => {
|
|
62
|
-
const {
|
|
63
|
-
token,
|
|
64
|
-
categories,
|
|
65
|
-
numberOfColumnsToShow = 1,
|
|
66
|
-
numberOfRowsToStart,
|
|
67
|
-
getOffset,
|
|
68
|
-
entriesToRemove,
|
|
69
|
-
id
|
|
70
|
-
} = props;
|
|
71
|
-
const baseVariables = {
|
|
72
|
-
token,
|
|
73
|
-
limit: numberOfColumnsToShow * numberOfRowsToStart,
|
|
74
|
-
offset: getOffset ? getOffset() : 0
|
|
75
|
-
};
|
|
76
|
-
if (categories) {
|
|
77
|
-
baseVariables.categories = categories;
|
|
78
|
-
}
|
|
79
|
-
if (entriesToRemove) {
|
|
80
|
-
baseVariables.entriesToRemove = entriesToRemove;
|
|
81
|
-
}
|
|
82
|
-
if (id) {
|
|
83
|
-
baseVariables.id = id;
|
|
84
|
-
}
|
|
85
|
-
if (composeVariables) {
|
|
86
|
-
return composeVariables(baseVariables);
|
|
87
|
-
}
|
|
88
|
-
const defaultVariables = { ...baseVariables };
|
|
89
|
-
if (categories) {
|
|
90
|
-
defaultVariables.related = categories;
|
|
91
|
-
delete defaultVariables.categories;
|
|
92
|
-
}
|
|
93
|
-
return defaultVariables;
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
export {
|
|
98
|
-
createGraphQLFetchStrategy
|
|
99
|
-
};
|
|
100
|
-
//# sourceMappingURL=graphql.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"graphql.mjs","sources":["../../../source/strategies/fetch/graphql.ts"],"sourcesContent":["/**\n * GraphQL Fetch Strategy Factory\n *\n * Generic factory for creating GraphQL-based fetch strategies.\n * Handles common GraphQL patterns: queries, variables, transformations.\n *\n * @module strategies/fetch/graphql\n */\n\nimport {\n fetchGraphQL,\n GraphQLVariables,\n} from '@universityofmaryland/web-utilities-library/network';\nimport { FetchStrategy } from '../../factory/core/types';\n\n/**\n * Configuration for creating a GraphQL fetch strategy\n */\nexport interface GraphQLFetchConfig<TData, TResponse = any> {\n /** GraphQL endpoint URL */\n endpoint: string;\n\n /** GraphQL queries */\n queries: {\n /** Query for fetching entries */\n entries: string;\n /** Optional separate query for count (if not in entries query) */\n count?: string;\n };\n\n /** Transform GraphQL response to entries array */\n transformResponse: (data: TResponse) => TData[] | null;\n\n /** Transform GraphQL response to count */\n transformCount: (data: TResponse) => number;\n\n /** Optional: Compose additional variables */\n composeVariables?: (baseVariables: any) => any;\n}\n\n/**\n * Create a GraphQL fetch strategy\n *\n * This factory handles the common patterns for GraphQL APIs:\n * - Fetching with variables\n * - Response transformation\n * - Count vs entries queries\n * - Error handling\n *\n * @template TData - The type of entry data\n * @template TResponse - The type of raw GraphQL response\n * @template TVariables - The type of GraphQL variables\n *\n * @param config - Configuration for the strategy\n * @returns Fetch strategy for use with createBaseFeed\n *\n * @example\n * ```typescript\n * const eventsFetchStrategy = createGraphQLFetchStrategy({\n * endpoint: 'https://calendar.umd.edu/graphql',\n * queries: {\n * entries: EVENTS_QUERY,\n * count: EVENTS_COUNT_QUERY,\n * },\n * transformResponse: (data) => data?.data?.entries?.events || null,\n * transformCount: (data) => data?.data?.count?.events?.length || 0,\n * });\n * ```\n */\nexport function createGraphQLFetchStrategy<\n TData,\n TResponse = any,\n TVariables = any,\n>(\n config: GraphQLFetchConfig<TData, TResponse>,\n): FetchStrategy<TData, TVariables> {\n const {\n endpoint,\n queries,\n transformResponse,\n transformCount,\n composeVariables,\n } = config;\n\n return {\n /**\n * Fetch the total count of entries\n */\n fetchCount: async (variables: TVariables): Promise<number | null> => {\n try {\n // Use count query if provided, otherwise use entries query\n const query = queries.count || queries.entries;\n const response = await fetchGraphQL({\n url: endpoint,\n query,\n token: (variables as any).token,\n variables: variables as GraphQLVariables,\n });\n\n // Check for errors\n if (!response || !response.data || response.message) {\n if (response?.message) {\n console.error(`GraphQL Error: ${response.message}`);\n }\n return null;\n }\n\n return transformCount(response);\n } catch (error) {\n console.error('Fetch count error:', error);\n return null;\n }\n },\n\n /**\n * Fetch the actual entries\n */\n fetchEntries: async (variables: TVariables): Promise<TData[] | null> => {\n try {\n const response = await fetchGraphQL({\n url: endpoint,\n query: queries.entries,\n token: (variables as any).token,\n variables: variables as GraphQLVariables,\n });\n\n // Check for errors\n if (!response || !response.data || response.message) {\n if (response?.message) {\n console.error(`GraphQL Error: ${response.message}`);\n }\n return null;\n }\n\n return transformResponse(response);\n } catch (error) {\n console.error('Fetch entries error:', error);\n return null;\n }\n },\n\n /**\n * Compose API variables from feed props\n */\n composeApiVariables: (props: any): TVariables => {\n const {\n token,\n categories,\n numberOfColumnsToShow = 1,\n numberOfRowsToStart,\n getOffset,\n entriesToRemove,\n id,\n } = props;\n\n // Base variables - pass all props through\n const baseVariables: any = {\n token,\n limit: numberOfColumnsToShow * numberOfRowsToStart,\n offset: getOffset ? getOffset() : 0,\n };\n\n // Pass categories through (let composeVariables decide how to map it)\n if (categories) {\n baseVariables.categories = categories;\n }\n\n // Pass entriesToRemove through\n if (entriesToRemove) {\n baseVariables.entriesToRemove = entriesToRemove;\n }\n\n // Pass id through\n if (id) {\n baseVariables.id = id;\n }\n\n // Allow custom variable composition\n if (composeVariables) {\n return composeVariables(baseVariables);\n }\n\n // Default mapping (for strategies without custom composeVariables)\n const defaultVariables: any = { ...baseVariables };\n\n // Default: map categories to 'related' if not customized\n if (categories) {\n defaultVariables.related = categories;\n delete defaultVariables.categories;\n }\n\n return defaultVariables as TVariables;\n },\n };\n}\n"],"names":[],"mappings":";AAqEO,SAAS,2BAKd,QACkC;AAClC,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,IACE;AAEJ,SAAO;AAAA;AAAA;AAAA;AAAA,IAIL,YAAY,OAAO,cAAkD;AACnE,UAAI;AAEF,cAAM,QAAQ,QAAQ,SAAS,QAAQ;AACvC,cAAM,WAAW,MAAM,aAAa;AAAA,UAClC,KAAK;AAAA,UACL;AAAA,UACA,OAAQ,UAAkB;AAAA,UAC1B;AAAA,QAAA,CACD;AAGD,YAAI,CAAC,YAAY,CAAC,SAAS,QAAQ,SAAS,SAAS;AACnD,cAAI,UAAU,SAAS;AACrB,oBAAQ,MAAM,kBAAkB,SAAS,OAAO,EAAE;AAAA,UACpD;AACA,iBAAO;AAAA,QACT;AAEA,eAAO,eAAe,QAAQ;AAAA,MAChC,SAAS,OAAO;AACd,gBAAQ,MAAM,sBAAsB,KAAK;AACzC,eAAO;AAAA,MACT;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKA,cAAc,OAAO,cAAmD;AACtE,UAAI;AACF,cAAM,WAAW,MAAM,aAAa;AAAA,UAClC,KAAK;AAAA,UACL,OAAO,QAAQ;AAAA,UACf,OAAQ,UAAkB;AAAA,UAC1B;AAAA,QAAA,CACD;AAGD,YAAI,CAAC,YAAY,CAAC,SAAS,QAAQ,SAAS,SAAS;AACnD,cAAI,UAAU,SAAS;AACrB,oBAAQ,MAAM,kBAAkB,SAAS,OAAO,EAAE;AAAA,UACpD;AACA,iBAAO;AAAA,QACT;AAEA,eAAO,kBAAkB,QAAQ;AAAA,MACnC,SAAS,OAAO;AACd,gBAAQ,MAAM,wBAAwB,KAAK;AAC3C,eAAO;AAAA,MACT;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKA,qBAAqB,CAAC,UAA2B;AAC/C,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA,wBAAwB;AAAA,QACxB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA,IACE;AAGJ,YAAM,gBAAqB;AAAA,QACzB;AAAA,QACA,OAAO,wBAAwB;AAAA,QAC/B,QAAQ,YAAY,cAAc;AAAA,MAAA;AAIpC,UAAI,YAAY;AACd,sBAAc,aAAa;AAAA,MAC7B;AAGA,UAAI,iBAAiB;AACnB,sBAAc,kBAAkB;AAAA,MAClC;AAGA,UAAI,IAAI;AACN,sBAAc,KAAK;AAAA,MACrB;AAGA,UAAI,kBAAkB;AACpB,eAAO,iBAAiB,aAAa;AAAA,MACvC;AAGA,YAAM,mBAAwB,EAAE,GAAG,cAAA;AAGnC,UAAI,YAAY;AACd,yBAAiB,UAAU;AAC3B,eAAO,iBAAiB;AAAA,MAC1B;AAEA,aAAO;AAAA,IACT;AAAA,EAAA;AAEJ;"}
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import { createGraphQLFetchStrategy } from "./graphql.mjs";
|
|
2
|
-
const FRAGMENT_ARTICLE_BASIC = `
|
|
3
|
-
fragment ArticleBasicFields on articles_today_Entry {
|
|
4
|
-
id
|
|
5
|
-
title
|
|
6
|
-
url
|
|
7
|
-
}
|
|
8
|
-
`;
|
|
9
|
-
const FRAGMENT_ARTICLE_DATES = `
|
|
10
|
-
fragment ArticleDateFields on articles_today_Entry {
|
|
11
|
-
date: postDate
|
|
12
|
-
dateFormatted: postDate @formatDateTime(format: "M d, Y")
|
|
13
|
-
}
|
|
14
|
-
`;
|
|
15
|
-
const FRAGMENT_ARTICLE_CONTENT = `
|
|
16
|
-
fragment ArticleContentFields on articles_today_Entry {
|
|
17
|
-
summary: genericText
|
|
18
|
-
image: articlesHeroImage {
|
|
19
|
-
url
|
|
20
|
-
... on hero_Asset {
|
|
21
|
-
id
|
|
22
|
-
altText: genericText
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
`;
|
|
27
|
-
const FRAGMENT_ARTICLE_CATEGORIES = `
|
|
28
|
-
fragment ArticleCategoryFields on articles_today_Entry {
|
|
29
|
-
categories: categoryTodaySectionMultiple {
|
|
30
|
-
title
|
|
31
|
-
url
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
`;
|
|
35
|
-
const ARTICLES_QUERY = `
|
|
36
|
-
query getArticles($related: [QueryArgument], $relatedToAll: [QueryArgument], $limit: Int, $offset: Int, $not: [QueryArgument]) {
|
|
37
|
-
entryCount(section: "articles", relatedTo: $related, relatedToAll: $relatedToAll)
|
|
38
|
-
entries(
|
|
39
|
-
section: "articles",
|
|
40
|
-
relatedTo: $related,
|
|
41
|
-
relatedToAll: $relatedToAll,
|
|
42
|
-
limit: $limit,
|
|
43
|
-
offset: $offset,
|
|
44
|
-
id: $not
|
|
45
|
-
) {
|
|
46
|
-
... on articles_today_Entry {
|
|
47
|
-
...ArticleBasicFields
|
|
48
|
-
...ArticleDateFields
|
|
49
|
-
...ArticleContentFields
|
|
50
|
-
...ArticleCategoryFields
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
${FRAGMENT_ARTICLE_BASIC}
|
|
55
|
-
${FRAGMENT_ARTICLE_DATES}
|
|
56
|
-
${FRAGMENT_ARTICLE_CONTENT}
|
|
57
|
-
${FRAGMENT_ARTICLE_CATEGORIES}
|
|
58
|
-
`;
|
|
59
|
-
const newsFetchStrategy = createGraphQLFetchStrategy({
|
|
60
|
-
endpoint: "https://today.umd.edu/graphql",
|
|
61
|
-
queries: {
|
|
62
|
-
entries: ARTICLES_QUERY
|
|
63
|
-
},
|
|
64
|
-
transformResponse: (data) => {
|
|
65
|
-
if (!data || !data.data || !data.data.entries) {
|
|
66
|
-
return null;
|
|
67
|
-
}
|
|
68
|
-
return data.data.entries || null;
|
|
69
|
-
},
|
|
70
|
-
transformCount: (data) => {
|
|
71
|
-
if (!data || !data.data) {
|
|
72
|
-
return 0;
|
|
73
|
-
}
|
|
74
|
-
return data.data.entryCount || 0;
|
|
75
|
-
},
|
|
76
|
-
composeVariables: (baseVariables) => {
|
|
77
|
-
const { categories, isUnion, entriesToRemove, ...rest } = baseVariables;
|
|
78
|
-
const variables = { ...rest };
|
|
79
|
-
if (!isUnion && categories) {
|
|
80
|
-
variables.relatedToAll = categories;
|
|
81
|
-
}
|
|
82
|
-
if (isUnion && categories) {
|
|
83
|
-
variables.related = categories;
|
|
84
|
-
}
|
|
85
|
-
if (entriesToRemove) {
|
|
86
|
-
variables.not = ["not", ...entriesToRemove];
|
|
87
|
-
}
|
|
88
|
-
return variables;
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
export {
|
|
92
|
-
ARTICLES_QUERY,
|
|
93
|
-
newsFetchStrategy
|
|
94
|
-
};
|
|
95
|
-
//# sourceMappingURL=news.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"news.mjs","sources":["../../../source/strategies/fetch/news.ts"],"sourcesContent":["/**\n * News Fetch Strategy\n *\n * Strategy for fetching news article data from the Maryland Today GraphQL API.\n *\n * @module strategies/fetch/news\n */\n\nimport { createGraphQLFetchStrategy } from './graphql';\nimport { NewsEntry } from 'types/data';\n\n/**\n * GraphQL fragments for news article data\n */\nconst FRAGMENT_ARTICLE_BASIC = `\n fragment ArticleBasicFields on articles_today_Entry {\n id\n title\n url\n }\n`;\n\nconst FRAGMENT_ARTICLE_DATES = `\n fragment ArticleDateFields on articles_today_Entry {\n date: postDate\n dateFormatted: postDate @formatDateTime(format: \"M d, Y\")\n }\n`;\n\nconst FRAGMENT_ARTICLE_CONTENT = `\n fragment ArticleContentFields on articles_today_Entry {\n summary: genericText\n image: articlesHeroImage {\n url\n ... on hero_Asset {\n id\n altText: genericText\n }\n }\n }\n`;\n\nconst FRAGMENT_ARTICLE_CATEGORIES = `\n fragment ArticleCategoryFields on articles_today_Entry {\n categories: categoryTodaySectionMultiple {\n title\n url\n }\n }\n`;\n\n/**\n * GraphQL query for news articles\n */\nexport const ARTICLES_QUERY = `\n query getArticles($related: [QueryArgument], $relatedToAll: [QueryArgument], $limit: Int, $offset: Int, $not: [QueryArgument]) {\n entryCount(section: \"articles\", relatedTo: $related, relatedToAll: $relatedToAll)\n entries(\n section: \"articles\",\n relatedTo: $related,\n relatedToAll: $relatedToAll,\n limit: $limit,\n offset: $offset,\n id: $not\n ) {\n ... on articles_today_Entry {\n ...ArticleBasicFields\n ...ArticleDateFields\n ...ArticleContentFields\n ...ArticleCategoryFields\n }\n }\n }\n ${FRAGMENT_ARTICLE_BASIC}\n ${FRAGMENT_ARTICLE_DATES}\n ${FRAGMENT_ARTICLE_CONTENT}\n ${FRAGMENT_ARTICLE_CATEGORIES}\n`;\n\n/**\n * News fetch strategy\n *\n * Fetches news article data from the Maryland Today GraphQL API.\n * Handles category filtering (both union and intersection), pagination,\n * and entry exclusion.\n *\n * @example\n * ```typescript\n * const feed = createBaseFeed({\n * token: 'my-token',\n * fetchStrategy: newsFetchStrategy,\n * categories: ['research', 'campus-news'],\n * // ...\n * });\n * ```\n */\nexport const newsFetchStrategy = createGraphQLFetchStrategy<NewsEntry>({\n endpoint: 'https://today.umd.edu/graphql',\n\n queries: {\n entries: ARTICLES_QUERY,\n },\n\n transformResponse: (data) => {\n if (!data || !data.data || !data.data.entries) {\n return null;\n }\n return data.data.entries || null;\n },\n\n transformCount: (data) => {\n if (!data || !data.data) {\n return 0;\n }\n return data.data.entryCount || 0;\n },\n\n composeVariables: (baseVariables) => {\n const { categories, isUnion, entriesToRemove, ...rest } = baseVariables;\n\n const variables: any = { ...rest };\n\n // Handle categories (union vs intersection)\n if (!isUnion && categories) {\n variables.relatedToAll = categories;\n }\n\n if (isUnion && categories) {\n variables.related = categories;\n }\n\n // Handle entry exclusion\n if (entriesToRemove) {\n variables.not = ['not', ...entriesToRemove];\n }\n\n return variables;\n },\n});\n"],"names":[],"mappings":";AAcA,MAAM,yBAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQ/B,MAAM,yBAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAO/B,MAAM,2BAA2B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAajC,MAAM,8BAA8B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAY7B,MAAM,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAmB1B,sBAAsB;AAAA,IACtB,sBAAsB;AAAA,IACtB,wBAAwB;AAAA,IACxB,2BAA2B;AAAA;AAoBxB,MAAM,oBAAoB,2BAAsC;AAAA,EACrE,UAAU;AAAA,EAEV,SAAS;AAAA,IACP,SAAS;AAAA,EAAA;AAAA,EAGX,mBAAmB,CAAC,SAAS;AAC3B,QAAI,CAAC,QAAQ,CAAC,KAAK,QAAQ,CAAC,KAAK,KAAK,SAAS;AAC7C,aAAO;AAAA,IACT;AACA,WAAO,KAAK,KAAK,WAAW;AAAA,EAC9B;AAAA,EAEA,gBAAgB,CAAC,SAAS;AACxB,QAAI,CAAC,QAAQ,CAAC,KAAK,MAAM;AACvB,aAAO;AAAA,IACT;AACA,WAAO,KAAK,KAAK,cAAc;AAAA,EACjC;AAAA,EAEA,kBAAkB,CAAC,kBAAkB;AACnC,UAAM,EAAE,YAAY,SAAS,iBAAiB,GAAG,SAAS;AAE1D,UAAM,YAAiB,EAAE,GAAG,KAAA;AAG5B,QAAI,CAAC,WAAW,YAAY;AAC1B,gBAAU,eAAe;AAAA,IAC3B;AAEA,QAAI,WAAW,YAAY;AACzB,gBAAU,UAAU;AAAA,IACtB;AAGA,QAAI,iBAAiB;AACnB,gBAAU,MAAM,CAAC,OAAO,GAAG,eAAe;AAAA,IAC5C;AAEA,WAAO;AAAA,EACT;AACF,CAAC;"}
|