@oomol-lab/open-connector 1.6.2 → 1.6.3

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 (168) hide show
  1. package/README.md +27 -0
  2. package/assets/open-connector/catalog/apps/assured_platform.json +218 -0
  3. package/assets/open-connector/catalog/apps/baixiao.json +1080 -0
  4. package/assets/open-connector/catalog/apps/benchmarkone.json +956 -0
  5. package/assets/open-connector/catalog/apps/bing_webmaster.json +3097 -0
  6. package/assets/open-connector/catalog/apps/buzzsprout.json +1979 -0
  7. package/assets/open-connector/catalog/apps/feishu.json +13 -19
  8. package/assets/open-connector/catalog/apps/feishu_app_bot.json +10 -17
  9. package/assets/open-connector/catalog/apps/linkfox.json +836 -0
  10. package/assets/open-connector/catalog/apps/metatraderapi.json +1077 -0
  11. package/assets/open-connector/catalog/apps/mktindex.json +2411 -0
  12. package/assets/open-connector/catalog/apps/mojo_helpdesk.json +660 -0
  13. package/assets/open-connector/catalog/apps/mumble.json +446 -0
  14. package/assets/open-connector/catalog/apps/notion.json +112 -3
  15. package/assets/open-connector/catalog/apps/omise.json +438 -0
  16. package/assets/open-connector/catalog/apps/panjiva.json +2858 -0
  17. package/assets/open-connector/catalog/apps/papertrail.json +449 -0
  18. package/assets/open-connector/catalog/apps/peec.json +747 -0
  19. package/assets/open-connector/catalog/apps/polygon_io.json +5156 -584
  20. package/assets/open-connector/catalog/apps/quant_data.json +1928 -0
  21. package/assets/open-connector/catalog/apps/riddle_quiz_maker.json +621 -0
  22. package/assets/open-connector/catalog/apps/slack.json +327 -4
  23. package/assets/open-connector/catalog/apps/slackbot.json +280 -3
  24. package/assets/open-connector/catalog/apps/templatedocs.json +438 -0
  25. package/assets/open-connector/catalog/apps/terminus_app.json +510 -0
  26. package/assets/open-connector/catalog/apps/ticket_tailor.json +584 -0
  27. package/assets/open-connector/catalog/apps/tongdaxin.json +2612 -79
  28. package/assets/open-connector/catalog/apps/veremark.json +514 -0
  29. package/assets/open-connector/catalog/apps/walletap.json +549 -0
  30. package/assets/open-connector/catalog/apps/xiaohongshu_store.json +955 -39
  31. package/assets/open-connector/catalog/apps-index.json +1 -1
  32. package/package.json +5 -1
  33. package/src/connection-service.d.ts +2 -0
  34. package/src/connection-service.js +8 -1
  35. package/src/core/provider-id.d.ts +5 -0
  36. package/src/core/provider-id.js +12 -0
  37. package/src/oauth/oauth-credential-refresh-service.js +2 -0
  38. package/src/oauth/oauth-flow-service.js +2 -0
  39. package/src/providers/action-contracts.generated.d.ts +27 -7
  40. package/src/providers/assured_platform/executors.d.ts +4 -0
  41. package/src/providers/assured_platform/executors.js +18 -0
  42. package/src/providers/assured_platform/runtime.d.ts +7 -0
  43. package/src/providers/assured_platform/runtime.js +108 -0
  44. package/src/providers/baixiao/actions.d.ts +2 -0
  45. package/src/providers/baixiao/actions.js +377 -0
  46. package/src/providers/baixiao/executors.d.ts +4 -0
  47. package/src/providers/baixiao/executors.js +106 -0
  48. package/src/providers/benchmarkone/executors.d.ts +4 -0
  49. package/src/providers/benchmarkone/executors.js +26 -0
  50. package/src/providers/benchmarkone/runtime.d.ts +12 -0
  51. package/src/providers/benchmarkone/runtime.js +113 -0
  52. package/src/providers/bing_webmaster/actions.d.ts +2 -0
  53. package/src/providers/bing_webmaster/actions.js +113 -0
  54. package/src/providers/bing_webmaster/executors.d.ts +4 -0
  55. package/src/providers/bing_webmaster/executors.js +104 -0
  56. package/src/providers/bing_webmaster/management-actions.d.ts +2 -0
  57. package/src/providers/bing_webmaster/management-actions.js +241 -0
  58. package/src/providers/bing_webmaster/reporting-actions.d.ts +2 -0
  59. package/src/providers/bing_webmaster/reporting-actions.js +300 -0
  60. package/src/providers/bing_webmaster/schemas.d.ts +33 -0
  61. package/src/providers/bing_webmaster/schemas.js +313 -0
  62. package/src/providers/buzzsprout/executors.d.ts +4 -0
  63. package/src/providers/buzzsprout/executors.js +21 -0
  64. package/src/providers/buzzsprout/runtime.d.ts +12 -0
  65. package/src/providers/buzzsprout/runtime.js +237 -0
  66. package/src/providers/feishu/shared/drive-actions.d.ts +1 -0
  67. package/src/providers/feishu/shared/drive-actions.js +13 -9
  68. package/src/providers/feishu/shared/drive-runtime.js +15 -3
  69. package/src/providers/feishu/shared/wiki-actions.js +4 -2
  70. package/src/providers/hithink_finance/runtime.js +39 -60
  71. package/src/providers/linkfox/actions.js +2 -0
  72. package/src/providers/linkfox/runtime.js +70 -1
  73. package/src/providers/linkfox/sif-actions.d.ts +10 -0
  74. package/src/providers/linkfox/sif-actions.js +193 -0
  75. package/src/providers/metatraderapi/executors.d.ts +4 -0
  76. package/src/providers/metatraderapi/executors.js +18 -0
  77. package/src/providers/metatraderapi/runtime.d.ts +7 -0
  78. package/src/providers/metatraderapi/runtime.js +216 -0
  79. package/src/providers/mktindex/actions-mmi.d.ts +2 -0
  80. package/src/providers/mktindex/actions-mmi.js +510 -0
  81. package/src/providers/mktindex/actions.d.ts +2 -0
  82. package/src/providers/mktindex/actions.js +2 -0
  83. package/src/providers/mktindex/executors.d.ts +4 -0
  84. package/src/providers/mktindex/executors.js +27 -0
  85. package/src/providers/mktindex/request.d.ts +17 -0
  86. package/src/providers/mktindex/request.js +48 -0
  87. package/src/providers/mktindex/runtime.d.ts +9 -0
  88. package/src/providers/mktindex/runtime.js +492 -0
  89. package/src/providers/mojo_helpdesk/executors.d.ts +4 -0
  90. package/src/providers/mojo_helpdesk/executors.js +18 -0
  91. package/src/providers/mojo_helpdesk/runtime.d.ts +7 -0
  92. package/src/providers/mojo_helpdesk/runtime.js +173 -0
  93. package/src/providers/mumble/executors.d.ts +4 -0
  94. package/src/providers/mumble/executors.js +99 -0
  95. package/src/providers/notion/executors.d.ts +9 -0
  96. package/src/providers/notion/executors.js +161 -6
  97. package/src/providers/omise/executors.d.ts +4 -0
  98. package/src/providers/omise/executors.js +120 -0
  99. package/src/providers/panjiva/actions.d.ts +14 -0
  100. package/src/providers/panjiva/actions.js +389 -0
  101. package/src/providers/panjiva/executors.d.ts +4 -0
  102. package/src/providers/panjiva/executors.js +136 -0
  103. package/src/providers/papertrail/executors.d.ts +4 -0
  104. package/src/providers/papertrail/executors.js +15 -0
  105. package/src/providers/papertrail/runtime.d.ts +7 -0
  106. package/src/providers/papertrail/runtime.js +167 -0
  107. package/src/providers/peec/executors.d.ts +4 -0
  108. package/src/providers/peec/executors.js +15 -0
  109. package/src/providers/peec/runtime.d.ts +7 -0
  110. package/src/providers/peec/runtime.js +128 -0
  111. package/src/providers/polygon_io/actions.d.ts +2 -0
  112. package/src/providers/polygon_io/actions.js +282 -0
  113. package/src/providers/polygon_io/expanded-actions.d.ts +2 -0
  114. package/src/providers/polygon_io/expanded-actions.js +375 -0
  115. package/src/providers/polygon_io/expanded-runtime.d.ts +16 -0
  116. package/src/providers/polygon_io/expanded-runtime.js +277 -0
  117. package/src/providers/polygon_io/runtime.js +21 -2
  118. package/src/providers/quant_data/executors.d.ts +4 -0
  119. package/src/providers/quant_data/executors.js +15 -0
  120. package/src/providers/quant_data/runtime.d.ts +7 -0
  121. package/src/providers/quant_data/runtime.js +118 -0
  122. package/src/providers/registry.generated.js +20 -0
  123. package/src/providers/riddle_quiz_maker/executors.d.ts +4 -0
  124. package/src/providers/riddle_quiz_maker/executors.js +15 -0
  125. package/src/providers/riddle_quiz_maker/runtime.d.ts +7 -0
  126. package/src/providers/riddle_quiz_maker/runtime.js +145 -0
  127. package/src/providers/slack/actions.js +106 -3
  128. package/src/providers/slack/runtime.js +260 -36
  129. package/src/providers/slackbot/actions.js +1 -1
  130. package/src/providers/templatedocs/executors.d.ts +4 -0
  131. package/src/providers/templatedocs/executors.js +18 -0
  132. package/src/providers/templatedocs/runtime.d.ts +13 -0
  133. package/src/providers/templatedocs/runtime.js +151 -0
  134. package/src/providers/terminus_app/executors.d.ts +4 -0
  135. package/src/providers/terminus_app/executors.js +15 -0
  136. package/src/providers/terminus_app/runtime.d.ts +7 -0
  137. package/src/providers/terminus_app/runtime.js +172 -0
  138. package/src/providers/ticket_tailor/executors.d.ts +4 -0
  139. package/src/providers/ticket_tailor/executors.js +15 -0
  140. package/src/providers/ticket_tailor/runtime.d.ts +7 -0
  141. package/src/providers/ticket_tailor/runtime.js +152 -0
  142. package/src/providers/tongdaxin/actions.d.ts +1 -0
  143. package/src/providers/tongdaxin/actions.js +6 -3
  144. package/src/providers/tongdaxin/executors.js +51 -10
  145. package/src/providers/tongdaxin/named-action-output.d.ts +1 -0
  146. package/src/providers/tongdaxin/named-action-output.js +149 -0
  147. package/src/providers/tongdaxin/named-action-routing.d.ts +9 -0
  148. package/src/providers/tongdaxin/named-action-routing.js +417 -0
  149. package/src/providers/tongdaxin/named-actions.d.ts +2 -0
  150. package/src/providers/tongdaxin/named-actions.js +378 -0
  151. package/src/providers/veremark/executors.d.ts +4 -0
  152. package/src/providers/veremark/executors.js +129 -0
  153. package/src/providers/walletap/executors.d.ts +4 -0
  154. package/src/providers/walletap/executors.js +15 -0
  155. package/src/providers/walletap/runtime.d.ts +7 -0
  156. package/src/providers/walletap/runtime.js +147 -0
  157. package/src/providers/weixin_official_account/access-token.js +31 -7
  158. package/src/providers/weixin_store/access-token.js +33 -7
  159. package/src/providers/xiaohongshu_store/executors.js +152 -3
  160. package/src/server/api/openapi.js +3 -0
  161. package/src/server/connector-assets.d.ts +4 -0
  162. package/src/server/connector-assets.js +12 -0
  163. package/src/server/connector-build.d.ts +33 -0
  164. package/src/server/connector-build.js +73 -0
  165. package/src/server/connector-runtime.d.ts +1 -2
  166. package/src/server/connector-runtime.js +2 -8
  167. package/src/server/server-assets.d.ts +0 -28
  168. package/src/server/server-assets.js +0 -50
@@ -0,0 +1,492 @@
1
+ import { compactObject, looseArray, optionalInteger, optionalNumber, optionalNumberLike, optionalRecord, optionalString, recordOrEmpty, } from "../../core/cast.js";
2
+ import { providerInputError, requiredInputString, requiredResponseRecord } from "../provider-runtime.js";
3
+ import { mktindexApiBaseUrl, requestMktindexEnvelope, requestMktindexResult } from "./request.js";
4
+ const breakdownTypeByDimension = {
5
+ category: "cat",
6
+ brand: "brand",
7
+ province: "provice",
8
+ };
9
+ const regionBreakdownTypeByDimension = {
10
+ category: "cat",
11
+ brand: "brand",
12
+ city: "city",
13
+ };
14
+ const mktindexMmiActionHandlers = {
15
+ async list_categories(input, context) {
16
+ const result = requiredResponseRecord(await requestMktindexResult({
17
+ path: "/cats_tree",
18
+ apiKey: context.apiKey,
19
+ query: compactObject({
20
+ plat: requiredInputString(input.platform, "platform"),
21
+ rcid: optionalString(input.rootCategoryId),
22
+ lang: optionalString(input.language),
23
+ last_time: optionalString(input.lastUpdatedAt),
24
+ }),
25
+ fetcher: context.fetcher,
26
+ phase: "execute",
27
+ }), "Moojing category result");
28
+ const children = recordOrEmpty(result.childrenList);
29
+ return {
30
+ rootCategoryIds: looseArray(result.bigCategory).map(String),
31
+ maxDepth: optionalInteger(result.maxDepth) ?? null,
32
+ categories: Object.entries(children).flatMap(([fallbackId, value]) => {
33
+ const category = optionalRecord(value);
34
+ if (!category) {
35
+ return [];
36
+ }
37
+ return [
38
+ {
39
+ id: optionalString(category.category_id) ?? fallbackId,
40
+ name: optionalString(category.name) ?? null,
41
+ englishName: optionalString(category.category_name_en) ?? null,
42
+ parentId: optionalString(category.parent_id) ?? null,
43
+ level: optionalInteger(category.level) ?? null,
44
+ childIds: looseArray(category.chd).map(String),
45
+ hasBrand: typeof category.has_brand === "boolean"
46
+ ? category.has_brand
47
+ : typeof category.has_brand === "number"
48
+ ? category.has_brand !== 0
49
+ : null,
50
+ raw: category,
51
+ },
52
+ ];
53
+ }),
54
+ };
55
+ },
56
+ async get_data_range(input, context) {
57
+ const result = requiredResponseRecord(await requestMktindexResult({
58
+ path: "/latesttime",
59
+ apiKey: context.apiKey,
60
+ query: compactObject({
61
+ plat: requiredInputString(input.platform, "platform"),
62
+ cid: optionalString(input.categoryId),
63
+ bid: optionalString(input.brandId),
64
+ }),
65
+ fetcher: context.fetcher,
66
+ phase: "execute",
67
+ }), "Moojing data range result");
68
+ return {
69
+ startMonth: optionalString(result.start) ?? null,
70
+ endMonth: optionalString(result.end) ?? null,
71
+ raw: result,
72
+ };
73
+ },
74
+ async list_subscriptions(input, context) {
75
+ const result = requiredResponseRecord(await requestMktindexResult({
76
+ path: "/marked",
77
+ apiKey: context.apiKey,
78
+ query: compactObject({
79
+ isdashboard: input.mode === "subscribed" ? "true" : "false",
80
+ lang: optionalString(input.language),
81
+ }),
82
+ fetcher: context.fetcher,
83
+ phase: "execute",
84
+ }), "Moojing subscription result");
85
+ return {
86
+ subscriptions: objectArray(result.data),
87
+ };
88
+ },
89
+ async get_jd_data_versions(input, context) {
90
+ const platform = requiredInputString(input.platform, "platform");
91
+ const result = await requestMktindexResult({
92
+ path: `/platform/${encodeURIComponent(platform)}/version`,
93
+ apiKey: context.apiKey,
94
+ fetcher: context.fetcher,
95
+ phase: "execute",
96
+ });
97
+ return { versions: looseArray(result).map(String) };
98
+ },
99
+ async search_brands(input, context) {
100
+ const query = requiredInputString(input.query, "query");
101
+ const result = await requestMktindexResult({
102
+ path: `/search/${encodeURIComponent(query)}`,
103
+ apiKey: context.apiKey,
104
+ query: compactObject({ currency: optionalString(input.currency) }),
105
+ fetcher: context.fetcher,
106
+ phase: "execute",
107
+ });
108
+ return { results: objectArray(result) };
109
+ },
110
+ async get_market_summary(input, context) {
111
+ const result = requiredResponseRecord(await requestMarketEndpoint(input, context, "/summary", {
112
+ start: requiredInputString(input.month, "month"),
113
+ lang: requiredInputString(input.language, "language"),
114
+ }), "Moojing market summary result");
115
+ return normalizeMarketSummary(result);
116
+ },
117
+ async get_market_trend(input, context) {
118
+ const result = requiredResponseRecord(await requestMarketEndpoint(input, context, "/trend", {
119
+ type: requiredInputString(input.period, "period"),
120
+ YoY: input.includeYearOverYear === true ? "true" : undefined,
121
+ }), "Moojing market trend result");
122
+ return { series: result };
123
+ },
124
+ async list_market_breakdown(input, context) {
125
+ const dimension = requiredInputString(input.dimension, "dimension");
126
+ const upstreamType = breakdownTypeByDimension[dimension];
127
+ if (!upstreamType) {
128
+ throw providerInputError(`unsupported dimension: ${dimension}`);
129
+ }
130
+ const result = await requestPaginatedMarketEndpoint(input, context, "/list", {
131
+ type: upstreamType,
132
+ });
133
+ return { count: result.count, rows: result.rows };
134
+ },
135
+ async list_hot_shops(input, context) {
136
+ const result = await requestPaginatedMarketEndpoint(input, context, "/hot_shops");
137
+ return { count: result.count, shops: result.rows };
138
+ },
139
+ async list_hot_items(input, context) {
140
+ const result = await requestPaginatedMarketEndpoint(input, context, "/hot_items");
141
+ return { count: result.count, items: result.rows };
142
+ },
143
+ async compare_market_periods(input, context) {
144
+ return rawData(await requestMarketEndpoint(input, context, "/compare", {
145
+ compare_range: serializeComparisonRanges(input.ranges),
146
+ }));
147
+ },
148
+ async get_region_market_summary(input, context) {
149
+ return rawData(await requestRegionMarketEndpoint(input, context, "/summary", {
150
+ start: requiredInputString(input.month, "month"),
151
+ lang: requiredInputString(input.language, "language"),
152
+ }));
153
+ },
154
+ async get_region_market_trend(input, context) {
155
+ return rawData(await requestRegionMarketEndpoint(input, context, "/trend", {
156
+ type: requiredInputString(input.period, "period"),
157
+ }));
158
+ },
159
+ async list_region_market_breakdown(input, context) {
160
+ const dimension = requiredInputString(input.dimension, "dimension");
161
+ const upstreamType = regionBreakdownTypeByDimension[dimension];
162
+ if (!upstreamType) {
163
+ throw providerInputError(`unsupported region dimension: ${dimension}`);
164
+ }
165
+ return rawData(await requestRegionMarketEndpoint(input, context, "/list", {
166
+ start: requiredInputString(input.month, "month"),
167
+ type: upstreamType,
168
+ page: String(optionalInteger(input.page) ?? 1),
169
+ page_size: String(optionalInteger(input.pageSize) ?? 10),
170
+ }));
171
+ },
172
+ async list_region_hot_shops(input, context) {
173
+ return rawData(await requestRegionMarketEndpoint(input, context, "/hot_shops", {
174
+ start: requiredInputString(input.month, "month"),
175
+ page: String(optionalInteger(input.page) ?? 1),
176
+ page_size: String(optionalInteger(input.pageSize) ?? 10),
177
+ }));
178
+ },
179
+ async list_region_hot_items(input, context) {
180
+ return rawData(await requestRegionMarketEndpoint(input, context, "/hot_items", {
181
+ start: requiredInputString(input.month, "month"),
182
+ page: String(optionalInteger(input.page) ?? 1),
183
+ page_size: String(optionalInteger(input.pageSize) ?? 10),
184
+ }));
185
+ },
186
+ async compare_region_market_periods(input, context) {
187
+ return rawData(await requestRegionMarketEndpoint(input, context, "/compare", {
188
+ compare_range: serializeComparisonRanges(input.ranges),
189
+ }));
190
+ },
191
+ async get_comment_trend(input, context) {
192
+ return rawData(await requestMarketEndpoint(input, context, "/comment_trend", {
193
+ type: requiredInputString(input.period, "period"),
194
+ }));
195
+ },
196
+ async list_brand_categories(input, context) {
197
+ const platform = requiredInputString(input.platform, "platform");
198
+ const brandId = requiredInputString(input.brandId, "brandId");
199
+ const result = await requestMktindexResult({
200
+ path: `/brandcat/platform/${encodeURIComponent(platform)}/brand/${encodeURIComponent(brandId)}/cats`,
201
+ apiKey: context.apiKey,
202
+ query: compactObject({ currency: optionalString(input.currency) }),
203
+ fetcher: context.fetcher,
204
+ phase: "execute",
205
+ });
206
+ return { categories: objectArray(result) };
207
+ },
208
+ async get_price_distribution(input, context) {
209
+ assertPriceDistributionInput(input);
210
+ const result = requiredResponseRecord(await requestMarketEndpoint(input, context, "/price_range", {
211
+ start: requiredInputString(input.month, "month"),
212
+ pricelist: Array.isArray(input.priceBreakpoints) ? input.priceBreakpoints.map(String).join(",") : undefined,
213
+ interval_size: optionalNumberString(input.intervalSize),
214
+ min_price: optionalNumberString(input.minPrice),
215
+ max_price: optionalNumberString(input.maxPrice),
216
+ range_length: optionalNumberString(input.rangeCount),
217
+ }), "Moojing price distribution result");
218
+ return {
219
+ ranges: looseArray(result.price_range).flatMap((value) => {
220
+ if (!Array.isArray(value)) {
221
+ return [];
222
+ }
223
+ return [
224
+ {
225
+ label: String(value[0] ?? ""),
226
+ itemShare: optionalNumberLike(value[1]) ?? null,
227
+ sold: optionalNumberLike(value[2]) ?? null,
228
+ sales: optionalNumberLike(value[3]) ?? null,
229
+ raw: value,
230
+ },
231
+ ];
232
+ }),
233
+ };
234
+ },
235
+ async get_platform_sales_trends(input, context) {
236
+ return rawData(await requestMktindexResult({
237
+ path: "/summary",
238
+ apiKey: context.apiKey,
239
+ query: compactObject({
240
+ type: requiredInputString(input.period, "period"),
241
+ start: requiredInputString(input.startMonth, "startMonth"),
242
+ currency: optionalString(input.currency),
243
+ }),
244
+ fetcher: context.fetcher,
245
+ phase: "execute",
246
+ }));
247
+ },
248
+ async list_spus(input, context) {
249
+ return rawData(await requestMarketEndpoint(input, context, "/spu", {
250
+ start: requiredInputString(input.month, "month"),
251
+ }));
252
+ },
253
+ async get_spu(input, context) {
254
+ const platform = requiredInputString(input.platform, "platform");
255
+ const spuId = requiredInputString(input.spuId, "spuId");
256
+ return rawData(await requestMktindexResult({
257
+ path: `/platform/${encodeURIComponent(platform)}/spu/${encodeURIComponent(spuId)}`,
258
+ apiKey: context.apiKey,
259
+ query: compactObject({
260
+ start: requiredInputString(input.month, "month"),
261
+ currency: optionalString(input.currency),
262
+ }),
263
+ fetcher: context.fetcher,
264
+ phase: "execute",
265
+ }));
266
+ },
267
+ async list_category_attributes(input, context) {
268
+ const platform = requiredInputString(input.platform, "platform");
269
+ const categoryId = requiredInputString(input.categoryId, "categoryId");
270
+ return rawData(await requestMktindexResult({
271
+ path: `/platform/${encodeURIComponent(platform)}/cats/${encodeURIComponent(categoryId)}/attrtable`,
272
+ apiKey: context.apiKey,
273
+ query: { start: requiredInputString(input.month, "month") },
274
+ fetcher: context.fetcher,
275
+ phase: "execute",
276
+ }));
277
+ },
278
+ async list_attribute_performance(input, context) {
279
+ if (input.mode === "single_attribute" && optionalString(input.attributeName) === undefined) {
280
+ throw providerInputError("attributeName is required when mode is single_attribute");
281
+ }
282
+ const platform = requiredInputString(input.platform, "platform");
283
+ const categoryId = requiredInputString(input.categoryId, "categoryId");
284
+ return rawData(await requestMktindexResult({
285
+ path: `/platform/${encodeURIComponent(platform)}/cats/${encodeURIComponent(categoryId)}/attr_top`,
286
+ apiKey: context.apiKey,
287
+ query: compactObject({
288
+ start: requiredInputString(input.month, "month"),
289
+ type: input.mode === "single_attribute" ? "single" : "couple",
290
+ attr_name: optionalString(input.attributeName),
291
+ currency: optionalString(input.currency),
292
+ }),
293
+ fetcher: context.fetcher,
294
+ phase: "execute",
295
+ }));
296
+ },
297
+ async get_attribute_summary(input, context) {
298
+ const attributeCount = Object.keys(recordOrEmpty(input.attributes)).length;
299
+ if (attributeCount < 1 || attributeCount > 2) {
300
+ throw providerInputError("attributes must contain one or two selections");
301
+ }
302
+ const platform = requiredInputString(input.platform, "platform");
303
+ const categoryId = requiredInputString(input.categoryId, "categoryId");
304
+ return rawData(await requestMktindexResult({
305
+ path: `/platform/${encodeURIComponent(platform)}/cats/${encodeURIComponent(categoryId)}/attr_summary`,
306
+ apiKey: context.apiKey,
307
+ query: compactObject({
308
+ brandid: requiredInputString(input.brandId, "brandId"),
309
+ attrs: JSON.stringify(recordOrEmpty(input.attributes)),
310
+ start: requiredInputString(input.month, "month"),
311
+ currency: optionalString(input.currency),
312
+ }),
313
+ fetcher: context.fetcher,
314
+ phase: "execute",
315
+ }));
316
+ },
317
+ async get_shop_sales_trend(input, context) {
318
+ return rawData(await requestMktindexResult({
319
+ path: "/shop/sale/trend",
320
+ apiKey: context.apiKey,
321
+ query: compactObject({
322
+ plat: requiredInputString(input.platform, "platform"),
323
+ uid: requiredInputString(input.shopId, "shopId"),
324
+ cat_id: requiredInputString(input.categoryId, "categoryId"),
325
+ brand_id: requiredInputString(input.brandId, "brandId"),
326
+ start: requiredInputString(input.startMonth, "startMonth"),
327
+ currency: optionalString(input.currency),
328
+ }),
329
+ fetcher: context.fetcher,
330
+ phase: "execute",
331
+ }));
332
+ },
333
+ async get_item_sales_trend(input, context) {
334
+ return rawData(await requestMktindexResult({
335
+ path: "/item/sale/trend",
336
+ apiKey: context.apiKey,
337
+ query: compactObject({
338
+ plat: requiredInputString(input.platform, "platform"),
339
+ item_id: requiredInputString(input.itemId, "itemId"),
340
+ start: requiredInputString(input.startMonth, "startMonth"),
341
+ currency: optionalString(input.currency),
342
+ }),
343
+ fetcher: context.fetcher,
344
+ phase: "execute",
345
+ }));
346
+ },
347
+ async get_shop_details(input, context) {
348
+ assertShopDetailsInput(input);
349
+ const envelope = await requestMktindexEnvelope({
350
+ path: "/shopdetail",
351
+ apiKey: context.apiKey,
352
+ query: compactObject({
353
+ plat: requiredInputString(input.platform, "platform"),
354
+ start: requiredInputString(input.startMonth, "startMonth"),
355
+ end: optionalString(input.endMonth),
356
+ shopname: optionalStringList(input.shopNames),
357
+ id: optionalStringList(input.shopIds),
358
+ currency: optionalString(input.currency),
359
+ }),
360
+ fetcher: context.fetcher,
361
+ phase: "execute",
362
+ });
363
+ return {
364
+ shops: objectArray(envelope.result),
365
+ errors: looseArray(envelope.errors).map(String),
366
+ };
367
+ },
368
+ };
369
+ export const mktindexActionHandlers = { ...mktindexMmiActionHandlers };
370
+ export async function validateMktindexCredential(input, fetcher) {
371
+ requiredResponseRecord(await requestMktindexResult({
372
+ path: "/marked",
373
+ apiKey: requiredInputString(input.apiKey, "apiKey"),
374
+ query: { isdashboard: "true", lang: "zh" },
375
+ fetcher,
376
+ phase: "validate",
377
+ }), "Moojing credential validation result");
378
+ return {
379
+ profile: { displayName: "Moojing Insights API Key" },
380
+ grantedScopes: [],
381
+ metadata: {
382
+ apiBaseUrl: mktindexApiBaseUrl,
383
+ validationEndpoint: "/marked",
384
+ },
385
+ };
386
+ }
387
+ async function requestPaginatedMarketEndpoint(input, context, suffix, extraQuery = {}) {
388
+ const result = requiredResponseRecord(await requestMarketEndpoint(input, context, suffix, {
389
+ start: requiredInputString(input.month, "month"),
390
+ page: String(optionalInteger(input.page) ?? 1),
391
+ page_size: String(optionalInteger(input.pageSize) ?? 10),
392
+ ...extraQuery,
393
+ }), "Moojing paginated market result");
394
+ return {
395
+ count: optionalInteger(result.count) ?? 0,
396
+ rows: objectArray(result.data),
397
+ };
398
+ }
399
+ function requestMarketEndpoint(input, context, suffix, query) {
400
+ const platform = requiredInputString(input.platform, "platform");
401
+ const categoryId = requiredInputString(input.categoryId, "categoryId");
402
+ const brandId = requiredInputString(input.brandId, "brandId");
403
+ return requestMktindexResult({
404
+ path: `/platform/${encodeURIComponent(platform)}/cats/${encodeURIComponent(categoryId)}/brands/${encodeURIComponent(brandId)}${suffix}`,
405
+ apiKey: context.apiKey,
406
+ query: compactObject({ ...query, currency: optionalString(input.currency) }),
407
+ fetcher: context.fetcher,
408
+ phase: "execute",
409
+ });
410
+ }
411
+ function requestRegionMarketEndpoint(input, context, suffix, query) {
412
+ const platform = requiredInputString(input.platform, "platform");
413
+ const province = requiredInputString(input.province, "province");
414
+ const city = requiredInputString(input.city, "city");
415
+ const categoryId = requiredInputString(input.categoryId, "categoryId");
416
+ const brandId = requiredInputString(input.brandId, "brandId");
417
+ return requestMktindexResult({
418
+ path: `/platform/${encodeURIComponent(platform)}/province/${encodeURIComponent(province)}/city/${encodeURIComponent(city)}/cats/${encodeURIComponent(categoryId)}/brands/${encodeURIComponent(brandId)}${suffix}`,
419
+ apiKey: context.apiKey,
420
+ query: compactObject({ ...query, currency: optionalString(input.currency) }),
421
+ fetcher: context.fetcher,
422
+ phase: "execute",
423
+ });
424
+ }
425
+ function normalizeMarketSummary(result) {
426
+ return {
427
+ sales: optionalNumber(result.sales) ?? optionalNumber(result.sale) ?? null,
428
+ sold: optionalNumber(result.sold) ?? null,
429
+ averagePrice: optionalNumber(result.avg_price) ?? null,
430
+ marketShare: optionalNumber(result.market_share) ?? null,
431
+ shopCount: optionalNumber(result.shop_num) ?? null,
432
+ itemCount: optionalNumber(result.item_num) ?? null,
433
+ names: recordOrEmpty(result.names),
434
+ raw: result,
435
+ };
436
+ }
437
+ function serializeComparisonRanges(value) {
438
+ return JSON.stringify(looseArray(value).map((item) => {
439
+ const range = requiredResponseRecord(item, "comparison range");
440
+ const startMonth = requiredInputString(range.startMonth, "startMonth");
441
+ const endMonth = requiredInputString(range.endMonth, "endMonth");
442
+ if (monthIndex(endMonth) < monthIndex(startMonth)) {
443
+ throw providerInputError("endMonth must not be earlier than startMonth");
444
+ }
445
+ return `${startMonth},${endMonth}`;
446
+ }));
447
+ }
448
+ function assertPriceDistributionInput(input) {
449
+ const hasBreakpoints = Array.isArray(input.priceBreakpoints);
450
+ const hasGeneratedRange = [input.intervalSize, input.minPrice, input.maxPrice, input.rangeCount].every((value) => value !== undefined);
451
+ const generatedRangeIsOrdered = !hasGeneratedRange || (optionalNumber(input.maxPrice) ?? 0) > (optionalNumber(input.minPrice) ?? 0);
452
+ if (input.categoryId === "0" || hasBreakpoints === hasGeneratedRange || !generatedRangeIsOrdered) {
453
+ throw providerInputError("categoryId cannot be 0; provide priceBreakpoints or complete generated-range parameters, with maxPrice greater than minPrice");
454
+ }
455
+ }
456
+ function assertShopDetailsInput(input) {
457
+ if (Array.isArray(input.shopNames) === Array.isArray(input.shopIds)) {
458
+ throw providerInputError("Provide exactly one of shopNames or shopIds");
459
+ }
460
+ const endMonth = optionalString(input.endMonth);
461
+ if (endMonth === undefined)
462
+ return;
463
+ const startMonth = requiredInputString(input.startMonth, "startMonth");
464
+ const monthSpan = monthIndex(endMonth) - monthIndex(startMonth);
465
+ if (monthSpan < 0 || monthSpan > 12) {
466
+ throw providerInputError("endMonth must be between startMonth and 12 months after it");
467
+ }
468
+ }
469
+ function monthIndex(value) {
470
+ const separator = value.includes("-") ? "-" : "_";
471
+ const [year, month] = value.split(separator).map(Number);
472
+ if (!Number.isInteger(year) || !Number.isInteger(month) || month === undefined || month < 1 || month > 12) {
473
+ throw providerInputError("month must use YYYY-MM or YYYY_MM format");
474
+ }
475
+ return year * 12 + month;
476
+ }
477
+ function rawData(data) {
478
+ return { data };
479
+ }
480
+ function objectArray(value) {
481
+ return looseArray(value).flatMap((item) => {
482
+ const record = optionalRecord(item);
483
+ return record ? [record] : [];
484
+ });
485
+ }
486
+ function optionalNumberString(value) {
487
+ const number = optionalNumber(value);
488
+ return number === undefined ? undefined : String(number);
489
+ }
490
+ function optionalStringList(value) {
491
+ return Array.isArray(value) ? value.map(String).join(",") : undefined;
492
+ }
@@ -0,0 +1,4 @@
1
+ import type { CredentialValidators, ProviderExecutors, ProviderProxyExecutor } from "../../core/types.ts";
2
+ export declare const executors: ProviderExecutors;
3
+ export declare const proxy: ProviderProxyExecutor;
4
+ export declare const credentialValidators: CredentialValidators;
@@ -0,0 +1,18 @@
1
+ import { defineApiKeyProviderExecutors, defineProviderProxy } from "../provider-runtime.js";
2
+ import { mojoHelpdeskActionHandlers, mojoHelpdeskApiBaseUrl, validateMojoHelpdeskCredential } from "./runtime.js";
3
+ const service = "mojo_helpdesk";
4
+ export const executors = defineApiKeyProviderExecutors(service, mojoHelpdeskActionHandlers);
5
+ export const proxy = defineProviderProxy({
6
+ service,
7
+ baseUrl: mojoHelpdeskApiBaseUrl,
8
+ auth: { type: "api_key_header", name: "X-API-KEY" },
9
+ skipDnsValidation: true,
10
+ customizeRequest({ headers }) {
11
+ headers.set("accept", "application/json");
12
+ },
13
+ });
14
+ export const credentialValidators = {
15
+ apiKey(input, { fetcher, signal }) {
16
+ return validateMojoHelpdeskCredential(input.apiKey, fetcher, signal);
17
+ },
18
+ };
@@ -0,0 +1,7 @@
1
+ import type { CredentialValidationResult } from "../../core/types.ts";
2
+ import type { ApiKeyProviderContext, ProviderActionHandlers, ProviderFetch } from "../provider-runtime.ts";
3
+ export declare const mojoHelpdeskApiBaseUrl = "https://app.mojohelpdesk.com/api/v2";
4
+ type MojoHandler = (input: Record<string, unknown>, context: ApiKeyProviderContext) => Promise<unknown>;
5
+ export declare const mojoHelpdeskActionHandlers: ProviderActionHandlers<"mojo_helpdesk", MojoHandler>;
6
+ export declare function validateMojoHelpdeskCredential(apiKey: string, fetcher: ProviderFetch, signal?: AbortSignal): Promise<CredentialValidationResult>;
7
+ export {};