@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.
Files changed (207) hide show
  1. package/dist/academic.js +4 -4
  2. package/dist/academic.js.map +1 -1
  3. package/dist/events.js +10 -10
  4. package/dist/events.js.map +1 -1
  5. package/dist/experts.js +8 -8
  6. package/dist/experts.js.map +1 -1
  7. package/dist/factory/core/createBaseFeed.d.ts.map +1 -1
  8. package/dist/factory/core/createBaseFeed.js +19 -17
  9. package/dist/factory/core/createBaseFeed.js.map +1 -1
  10. package/dist/factory/core/types.d.ts +1 -0
  11. package/dist/factory/core/types.d.ts.map +1 -1
  12. package/dist/factory/helpers/displayHandler.js +29 -47
  13. package/dist/factory/helpers/displayHandler.js.map +1 -1
  14. package/dist/factory/helpers/feedHelpers.js +3 -3
  15. package/dist/factory/helpers/feedHelpers.js.map +1 -1
  16. package/dist/factory/helpers/fetchHandler.js +16 -33
  17. package/dist/factory/helpers/fetchHandler.js.map +1 -1
  18. package/dist/feeds/academic/index.d.ts +1 -1
  19. package/dist/feeds/academic/index.d.ts.map +1 -1
  20. package/dist/feeds/academic/slider.d.ts +1 -2
  21. package/dist/feeds/academic/slider.d.ts.map +1 -1
  22. package/dist/feeds/academic/slider.js +7 -6
  23. package/dist/feeds/academic/slider.js.map +1 -1
  24. package/dist/feeds/events/grid.d.ts +1 -2
  25. package/dist/feeds/events/grid.d.ts.map +1 -1
  26. package/dist/feeds/events/grid.js +22 -21
  27. package/dist/feeds/events/grid.js.map +1 -1
  28. package/dist/feeds/events/grouped.d.ts +1 -2
  29. package/dist/feeds/events/grouped.d.ts.map +1 -1
  30. package/dist/feeds/events/grouped.js +62 -78
  31. package/dist/feeds/events/grouped.js.map +1 -1
  32. package/dist/feeds/events/index.d.ts +4 -4
  33. package/dist/feeds/events/index.d.ts.map +1 -1
  34. package/dist/feeds/events/list.d.ts +1 -2
  35. package/dist/feeds/events/list.d.ts.map +1 -1
  36. package/dist/feeds/events/list.js +22 -21
  37. package/dist/feeds/events/list.js.map +1 -1
  38. package/dist/feeds/events/slider.d.ts +1 -2
  39. package/dist/feeds/events/slider.d.ts.map +1 -1
  40. package/dist/feeds/events/slider.js +7 -6
  41. package/dist/feeds/events/slider.js.map +1 -1
  42. package/dist/feeds/experts/_types.d.ts +2 -1
  43. package/dist/feeds/experts/_types.d.ts.map +1 -1
  44. package/dist/feeds/experts/bio.d.ts +1 -2
  45. package/dist/feeds/experts/bio.d.ts.map +1 -1
  46. package/dist/feeds/experts/bio.js +32 -31
  47. package/dist/feeds/experts/bio.js.map +1 -1
  48. package/dist/feeds/experts/grid.d.ts +1 -2
  49. package/dist/feeds/experts/grid.d.ts.map +1 -1
  50. package/dist/feeds/experts/grid.js +24 -23
  51. package/dist/feeds/experts/grid.js.map +1 -1
  52. package/dist/feeds/experts/index.d.ts +3 -3
  53. package/dist/feeds/experts/index.d.ts.map +1 -1
  54. package/dist/feeds/experts/list.d.ts +1 -2
  55. package/dist/feeds/experts/list.d.ts.map +1 -1
  56. package/dist/feeds/experts/list.js +23 -22
  57. package/dist/feeds/experts/list.js.map +1 -1
  58. package/dist/feeds/news/featured.d.ts +1 -2
  59. package/dist/feeds/news/featured.d.ts.map +1 -1
  60. package/dist/feeds/news/featured.js +56 -55
  61. package/dist/feeds/news/featured.js.map +1 -1
  62. package/dist/feeds/news/grid.d.ts +1 -2
  63. package/dist/feeds/news/grid.d.ts.map +1 -1
  64. package/dist/feeds/news/grid.js +24 -23
  65. package/dist/feeds/news/grid.js.map +1 -1
  66. package/dist/feeds/news/index.d.ts +3 -3
  67. package/dist/feeds/news/index.d.ts.map +1 -1
  68. package/dist/feeds/news/list.d.ts +1 -2
  69. package/dist/feeds/news/list.d.ts.map +1 -1
  70. package/dist/feeds/news/list.js +23 -22
  71. package/dist/feeds/news/list.js.map +1 -1
  72. package/dist/helpers/events/index.js +4 -4
  73. package/dist/helpers/events/index.js.map +1 -1
  74. package/dist/helpers/grouping/events.js +10 -10
  75. package/dist/helpers/grouping/events.js.map +1 -1
  76. package/dist/helpers/styles/shadow.js +5 -22
  77. package/dist/helpers/styles/shadow.js.map +1 -1
  78. package/dist/index.js +10 -10
  79. package/dist/index.js.map +1 -1
  80. package/dist/news.js +8 -8
  81. package/dist/news.js.map +1 -1
  82. package/dist/states/_types.d.ts +0 -24
  83. package/dist/states/_types.d.ts.map +1 -1
  84. package/dist/states/_types.js +3 -3
  85. package/dist/states/_types.js.map +1 -1
  86. package/dist/states/announcer.d.ts +1 -3
  87. package/dist/states/announcer.d.ts.map +1 -1
  88. package/dist/states/announcer.js +5 -5
  89. package/dist/states/announcer.js.map +1 -1
  90. package/dist/states/empty.d.ts +0 -2
  91. package/dist/states/empty.d.ts.map +1 -1
  92. package/dist/states/empty.js +15 -32
  93. package/dist/states/empty.js.map +1 -1
  94. package/dist/states/index.d.ts +4 -8
  95. package/dist/states/index.d.ts.map +1 -1
  96. package/dist/states/loading.d.ts +1 -3
  97. package/dist/states/loading.d.ts.map +1 -1
  98. package/dist/states/loading.js +16 -16
  99. package/dist/states/loading.js.map +1 -1
  100. package/dist/states/pagination.d.ts +1 -3
  101. package/dist/states/pagination.d.ts.map +1 -1
  102. package/dist/states/pagination.js +11 -28
  103. package/dist/states/pagination.js.map +1 -1
  104. package/dist/strategies/display/events.js +13 -13
  105. package/dist/strategies/display/events.js.map +1 -1
  106. package/dist/strategies/display/experts.js +23 -23
  107. package/dist/strategies/display/experts.js.map +1 -1
  108. package/dist/strategies/display/news.js +13 -13
  109. package/dist/strategies/display/news.js.map +1 -1
  110. package/dist/strategies/fetch/academic.js +3 -3
  111. package/dist/strategies/fetch/academic.js.map +1 -1
  112. package/dist/strategies/fetch/events.js +13 -13
  113. package/dist/strategies/fetch/events.js.map +1 -1
  114. package/dist/strategies/fetch/experts.d.ts +1 -1
  115. package/dist/strategies/fetch/experts.d.ts.map +1 -1
  116. package/dist/strategies/fetch/experts.js +13 -8
  117. package/dist/strategies/fetch/experts.js.map +1 -1
  118. package/dist/strategies/fetch/graphql.d.ts.map +1 -1
  119. package/dist/strategies/fetch/graphql.js +11 -7
  120. package/dist/strategies/fetch/graphql.js.map +1 -1
  121. package/dist/strategies/fetch/news.js +6 -6
  122. package/dist/strategies/fetch/news.js.map +1 -1
  123. package/dist/strategies/layout/grid.js +11 -11
  124. package/dist/strategies/layout/grid.js.map +1 -1
  125. package/dist/widgets/index.d.ts +1 -1
  126. package/dist/widgets/index.d.ts.map +1 -1
  127. package/dist/widgets/slider.d.ts +1 -2
  128. package/dist/widgets/slider.d.ts.map +1 -1
  129. package/dist/widgets/slider.js +19 -35
  130. package/dist/widgets/slider.js.map +1 -1
  131. package/package.json +15 -14
  132. package/dist/academic.mjs +0 -5
  133. package/dist/academic.mjs.map +0 -1
  134. package/dist/events.mjs +0 -11
  135. package/dist/events.mjs.map +0 -1
  136. package/dist/experts.mjs +0 -9
  137. package/dist/experts.mjs.map +0 -1
  138. package/dist/factory/core/createBaseFeed.mjs +0 -114
  139. package/dist/factory/core/createBaseFeed.mjs.map +0 -1
  140. package/dist/factory/helpers/displayHandler.mjs +0 -169
  141. package/dist/factory/helpers/displayHandler.mjs.map +0 -1
  142. package/dist/factory/helpers/feedHelpers.mjs +0 -32
  143. package/dist/factory/helpers/feedHelpers.mjs.map +0 -1
  144. package/dist/factory/helpers/fetchHandler.mjs +0 -123
  145. package/dist/factory/helpers/fetchHandler.mjs.map +0 -1
  146. package/dist/feeds/academic/slider.mjs +0 -11
  147. package/dist/feeds/academic/slider.mjs.map +0 -1
  148. package/dist/feeds/events/grid.mjs +0 -32
  149. package/dist/feeds/events/grid.mjs.map +0 -1
  150. package/dist/feeds/events/grouped.mjs +0 -337
  151. package/dist/feeds/events/grouped.mjs.map +0 -1
  152. package/dist/feeds/events/list.mjs +0 -33
  153. package/dist/feeds/events/list.mjs.map +0 -1
  154. package/dist/feeds/events/slider.mjs +0 -11
  155. package/dist/feeds/events/slider.mjs.map +0 -1
  156. package/dist/feeds/experts/bio.mjs +0 -147
  157. package/dist/feeds/experts/bio.mjs.map +0 -1
  158. package/dist/feeds/experts/grid.mjs +0 -37
  159. package/dist/feeds/experts/grid.mjs.map +0 -1
  160. package/dist/feeds/experts/list.mjs +0 -26
  161. package/dist/feeds/experts/list.mjs.map +0 -1
  162. package/dist/feeds/news/featured.mjs +0 -379
  163. package/dist/feeds/news/featured.mjs.map +0 -1
  164. package/dist/feeds/news/grid.mjs +0 -37
  165. package/dist/feeds/news/grid.mjs.map +0 -1
  166. package/dist/feeds/news/list.mjs +0 -34
  167. package/dist/feeds/news/list.mjs.map +0 -1
  168. package/dist/helpers/events/index.mjs +0 -21
  169. package/dist/helpers/events/index.mjs.map +0 -1
  170. package/dist/helpers/grouping/events.mjs +0 -147
  171. package/dist/helpers/grouping/events.mjs.map +0 -1
  172. package/dist/helpers/styles/shadow.mjs +0 -16
  173. package/dist/helpers/styles/shadow.mjs.map +0 -1
  174. package/dist/index.mjs +0 -11
  175. package/dist/index.mjs.map +0 -1
  176. package/dist/news.mjs +0 -9
  177. package/dist/news.mjs.map +0 -1
  178. package/dist/states/_types.mjs +0 -12
  179. package/dist/states/_types.mjs.map +0 -1
  180. package/dist/states/announcer.mjs +0 -62
  181. package/dist/states/announcer.mjs.map +0 -1
  182. package/dist/states/empty.mjs +0 -104
  183. package/dist/states/empty.mjs.map +0 -1
  184. package/dist/states/loading.mjs +0 -155
  185. package/dist/states/loading.mjs.map +0 -1
  186. package/dist/states/pagination.mjs +0 -102
  187. package/dist/states/pagination.mjs.map +0 -1
  188. package/dist/strategies/display/events.mjs +0 -60
  189. package/dist/strategies/display/events.mjs.map +0 -1
  190. package/dist/strategies/display/experts.mjs +0 -266
  191. package/dist/strategies/display/experts.mjs.map +0 -1
  192. package/dist/strategies/display/news.mjs +0 -58
  193. package/dist/strategies/display/news.mjs.map +0 -1
  194. package/dist/strategies/fetch/academic.mjs +0 -30
  195. package/dist/strategies/fetch/academic.mjs.map +0 -1
  196. package/dist/strategies/fetch/events.mjs +0 -223
  197. package/dist/strategies/fetch/events.mjs.map +0 -1
  198. package/dist/strategies/fetch/experts.mjs +0 -189
  199. package/dist/strategies/fetch/experts.mjs.map +0 -1
  200. package/dist/strategies/fetch/graphql.mjs +0 -100
  201. package/dist/strategies/fetch/graphql.mjs.map +0 -1
  202. package/dist/strategies/fetch/news.mjs +0 -95
  203. package/dist/strategies/fetch/news.mjs.map +0 -1
  204. package/dist/strategies/layout/grid.mjs +0 -36
  205. package/dist/strategies/layout/grid.mjs.map +0 -1
  206. package/dist/widgets/slider.mjs +0 -87
  207. 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;"}