@attlaz/client 1.95.0 → 1.97.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. package/dist/Catalog/Service/CatalogEndpoint.js +2 -1
  2. package/dist/Catalog/Service/CatalogProductEndpoint.js +3 -2
  3. package/dist/Client.d.ts +12 -12
  4. package/dist/Client.js +12 -12
  5. package/dist/{EnhanceData → DataEnrichment}/Service/GenerateContentEndpoint.js +3 -2
  6. package/dist/DataQuality/Model/QualityDataset.d.ts +1 -1
  7. package/dist/DataQuality/Model/QualityDataset.js +1 -1
  8. package/dist/DataQuality/Model/QualityEntity.d.ts +1 -1
  9. package/dist/DataQuality/Model/QualityEntity.js +1 -1
  10. package/dist/DataQuality/Model/{QualitySuppression.d.ts → QualityEntityProblemSuppression.d.ts} +3 -3
  11. package/dist/DataQuality/Model/{QualitySuppression.js → QualityEntityProblemSuppression.js} +3 -3
  12. package/dist/DataQuality/Model/QualityEntityProblemSuppressionResult.d.ts +6 -0
  13. package/dist/DataQuality/Model/QualityProblem.d.ts +1 -1
  14. package/dist/DataQuality/Model/QualityProblem.js +1 -1
  15. package/dist/DataQuality/Model/QualityProblemDefinition.d.ts +1 -1
  16. package/dist/DataQuality/Model/QualityProblemDefinition.js +1 -1
  17. package/dist/DataQuality/Model/QualityProblemEvent.d.ts +1 -1
  18. package/dist/DataQuality/Model/QualityProblemEvent.js +1 -1
  19. package/dist/DataQuality/Model/QualityReportEntity.d.ts +31 -0
  20. package/dist/DataQuality/Model/QualityReportEntity.js +44 -0
  21. package/dist/DataQuality/Model/QualityReportProblem.d.ts +22 -0
  22. package/dist/DataQuality/Model/QualityReportProblem.js +35 -0
  23. package/dist/DataQuality/Model/QualityReportResult.d.ts +9 -0
  24. package/dist/DataQuality/Model/QualityReportResult.js +14 -0
  25. package/dist/DataQuality/Model/QualityScan.d.ts +19 -0
  26. package/dist/DataQuality/Model/QualityScan.js +28 -0
  27. package/dist/DataQuality/Service/QualityEndpoint.d.ts +64 -7
  28. package/dist/DataQuality/Service/QualityEndpoint.js +116 -30
  29. package/dist/FeedManagement/Service/CatalogFeedEndpoint.js +2 -1
  30. package/dist/Flow/Service/FlowEndpoint.js +6 -5
  31. package/dist/Flow/Service/FlowRunEndpoint.js +8 -7
  32. package/dist/Flow/Service/FlowRunRequestEndpoint.js +2 -1
  33. package/dist/Flow/Service/FlowRunStatsEndpoint.js +2 -1
  34. package/dist/Helper/LoadAllHelper.js +7 -1
  35. package/dist/Http/Data/Path.d.ts +11 -0
  36. package/dist/Http/Data/Path.js +31 -0
  37. package/dist/Http/HttpClient.d.ts +8 -1
  38. package/dist/Http/HttpClient.js +21 -1
  39. package/dist/Http/OAuthClientOptions.d.ts +2 -0
  40. package/dist/Http/OAuthClientOptions.js +3 -0
  41. package/dist/Http/Transport/OAuthClient.d.ts +7 -0
  42. package/dist/Http/Transport/OAuthClient.js +31 -4
  43. package/dist/Logging/Service/LogEndpoint.d.ts +5 -1
  44. package/dist/Logging/Service/LogEndpoint.js +14 -8
  45. package/dist/{Pulse → MarketPulse}/Service/CompetitorEndpoint.js +4 -3
  46. package/dist/{Pulse → MarketPulse}/Service/CrawlJobEndpoint.d.ts +1 -0
  47. package/dist/{Pulse → MarketPulse}/Service/CrawlJobEndpoint.js +8 -6
  48. package/dist/{Pulse → MarketPulse}/Service/IndexJobEndpoint.js +5 -4
  49. package/dist/{Pulse → MarketPulse}/Service/PriceAlertEndpoint.js +8 -7
  50. package/dist/{Pulse → MarketPulse}/Service/PricingEndpoint.js +9 -8
  51. package/dist/{Pulse → MarketPulse}/Service/ProductGroupEndpoint.js +4 -3
  52. package/dist/{Pulse → MarketPulse}/Service/ProductMatchEndpoint.js +6 -5
  53. package/dist/{Pulse → MarketPulse}/Service/ProductMatchJobEndpoint.js +5 -4
  54. package/dist/{Pulse → MarketPulse}/Service/PulseCatalogProductEndpoint.js +4 -3
  55. package/dist/{Pulse → MarketPulse}/Service/PulseStatisticsEndpoint.js +5 -4
  56. package/dist/{Pulse → MarketPulse}/Service/VendorProductEndpoint.js +11 -7
  57. package/dist/Service/AccessTokenEndpoint.js +3 -2
  58. package/dist/Service/AdapterConnectionEndpoint.js +9 -8
  59. package/dist/Service/AdapterEndpoint.js +3 -2
  60. package/dist/Service/ChannelEndpoint.js +5 -4
  61. package/dist/Service/CodeDeployEndpoint.js +5 -4
  62. package/dist/Service/CodeSourceStrategiesEndpoint.js +3 -2
  63. package/dist/Service/CollectionsEndpoint.js +5 -4
  64. package/dist/Service/CommandExecutionEndpoint.js +2 -1
  65. package/dist/Service/ConfigEndpoint.d.ts +6 -1
  66. package/dist/Service/ConfigEndpoint.js +9 -3
  67. package/dist/Service/ConfigurationEndpoint.js +5 -4
  68. package/dist/Service/HealthAlertEndpoint.js +3 -2
  69. package/dist/Service/PlatformEndpoint.js +3 -2
  70. package/dist/Service/PlatformLanguageEndpoint.js +2 -1
  71. package/dist/Service/ProjectEndpoint.js +3 -2
  72. package/dist/Service/ProjectEnvironmentEndpoint.js +3 -2
  73. package/dist/Service/ProviderTokenEndpoint.js +4 -3
  74. package/dist/Service/RunnerPoolEndpoint.js +5 -4
  75. package/dist/Service/SourcesAccountEndpoint.js +6 -5
  76. package/dist/Service/StorageEndpoint.js +8 -7
  77. package/dist/Service/SubscriberEndpoint.js +4 -3
  78. package/dist/Service/TriggerEndpoint.js +5 -4
  79. package/dist/Service/UserActionEndpoint.js +4 -3
  80. package/dist/Service/UserEndpoint.js +3 -2
  81. package/dist/Service/WorkspaceEndpoint.js +2 -1
  82. package/dist/Service/WorkspaceMemberEndpoint.js +5 -4
  83. package/dist/index.d.ts +52 -48
  84. package/dist/index.js +38 -34
  85. package/dist/version.d.ts +1 -1
  86. package/dist/version.js +1 -1
  87. package/package.json +4 -2
  88. package/dist/DataQuality/Model/QualitySuppressionResult.d.ts +0 -6
  89. /package/dist/{EnhanceData → DataEnrichment}/Model/GenerateContentBatch.d.ts +0 -0
  90. /package/dist/{EnhanceData → DataEnrichment}/Model/GenerateContentBatch.js +0 -0
  91. /package/dist/{EnhanceData → DataEnrichment}/Model/GenerateContentBatchData.d.ts +0 -0
  92. /package/dist/{EnhanceData → DataEnrichment}/Model/GenerateContentBatchData.js +0 -0
  93. /package/dist/{EnhanceData → DataEnrichment}/Service/GenerateContentEndpoint.d.ts +0 -0
  94. /package/dist/DataQuality/Model/{QualitySuppressionResult.js → QualityEntityProblemSuppressionResult.js} +0 -0
  95. /package/dist/{Pulse → MarketPulse}/Model/CatalogProductWithMatches.d.ts +0 -0
  96. /package/dist/{Pulse → MarketPulse}/Model/CatalogProductWithMatches.js +0 -0
  97. /package/dist/{Pulse → MarketPulse}/Model/CompetingVendorProduct.d.ts +0 -0
  98. /package/dist/{Pulse → MarketPulse}/Model/CompetingVendorProduct.js +0 -0
  99. /package/dist/{Pulse → MarketPulse}/Model/Competitor.d.ts +0 -0
  100. /package/dist/{Pulse → MarketPulse}/Model/Competitor.js +0 -0
  101. /package/dist/{Pulse → MarketPulse}/Model/CrawlJob.d.ts +0 -0
  102. /package/dist/{Pulse → MarketPulse}/Model/CrawlJob.js +0 -0
  103. /package/dist/{Pulse → MarketPulse}/Model/IndexJob.d.ts +0 -0
  104. /package/dist/{Pulse → MarketPulse}/Model/IndexJob.js +0 -0
  105. /package/dist/{Pulse → MarketPulse}/Model/MarketSummaryEntry.d.ts +0 -0
  106. /package/dist/{Pulse → MarketPulse}/Model/MarketSummaryEntry.js +0 -0
  107. /package/dist/{Pulse → MarketPulse}/Model/MatchHistory.d.ts +0 -0
  108. /package/dist/{Pulse → MarketPulse}/Model/MatchHistory.js +0 -0
  109. /package/dist/{Pulse → MarketPulse}/Model/MatchHistoryBucket.d.ts +0 -0
  110. /package/dist/{Pulse → MarketPulse}/Model/MatchHistoryBucket.js +0 -0
  111. /package/dist/{Pulse → MarketPulse}/Model/MatchHistoryInterval.d.ts +0 -0
  112. /package/dist/{Pulse → MarketPulse}/Model/MatchHistoryInterval.js +0 -0
  113. /package/dist/{Pulse → MarketPulse}/Model/MatchedVendorProduct.d.ts +0 -0
  114. /package/dist/{Pulse → MarketPulse}/Model/MatchedVendorProduct.js +0 -0
  115. /package/dist/{Pulse → MarketPulse}/Model/PriceAlertConfig.d.ts +0 -0
  116. /package/dist/{Pulse → MarketPulse}/Model/PriceAlertConfig.js +0 -0
  117. /package/dist/{Pulse → MarketPulse}/Model/PriceAlertConfigData.d.ts +0 -0
  118. /package/dist/{Pulse → MarketPulse}/Model/PriceAlertConfigData.js +0 -0
  119. /package/dist/{Pulse → MarketPulse}/Model/PriceAlertEvent.d.ts +0 -0
  120. /package/dist/{Pulse → MarketPulse}/Model/PriceAlertEvent.js +0 -0
  121. /package/dist/{Pulse → MarketPulse}/Model/PriceIndexSnapshotEntry.d.ts +0 -0
  122. /package/dist/{Pulse → MarketPulse}/Model/PriceIndexSnapshotEntry.js +0 -0
  123. /package/dist/{Pulse → MarketPulse}/Model/PriceSuggestion.d.ts +0 -0
  124. /package/dist/{Pulse → MarketPulse}/Model/PriceSuggestion.js +0 -0
  125. /package/dist/{Pulse → MarketPulse}/Model/PricingRule.d.ts +0 -0
  126. /package/dist/{Pulse → MarketPulse}/Model/PricingRule.js +0 -0
  127. /package/dist/{Pulse → MarketPulse}/Model/PricingRuleData.d.ts +0 -0
  128. /package/dist/{Pulse → MarketPulse}/Model/PricingRuleData.js +0 -0
  129. /package/dist/{Pulse → MarketPulse}/Model/ProductGroup.d.ts +0 -0
  130. /package/dist/{Pulse → MarketPulse}/Model/ProductGroup.js +0 -0
  131. /package/dist/{Pulse → MarketPulse}/Model/ProductGroupData.d.ts +0 -0
  132. /package/dist/{Pulse → MarketPulse}/Model/ProductGroupData.js +0 -0
  133. /package/dist/{Pulse → MarketPulse}/Model/ProductMatch.d.ts +0 -0
  134. /package/dist/{Pulse → MarketPulse}/Model/ProductMatch.js +0 -0
  135. /package/dist/{Pulse → MarketPulse}/Model/ProductMatchJob.d.ts +0 -0
  136. /package/dist/{Pulse → MarketPulse}/Model/ProductMatchJob.js +0 -0
  137. /package/dist/{Pulse → MarketPulse}/Model/ProductSegmentType.d.ts +0 -0
  138. /package/dist/{Pulse → MarketPulse}/Model/ProductSegmentType.js +0 -0
  139. /package/dist/{Pulse → MarketPulse}/Model/ProductsSegment.d.ts +0 -0
  140. /package/dist/{Pulse → MarketPulse}/Model/ProductsSegment.js +0 -0
  141. /package/dist/{Pulse → MarketPulse}/Model/PulseCatalogProductFilterOptions.d.ts +0 -0
  142. /package/dist/{Pulse → MarketPulse}/Model/PulseCatalogProductFilterOptions.js +0 -0
  143. /package/dist/{Pulse → MarketPulse}/Model/PulseCatalogProductFilters.d.ts +0 -0
  144. /package/dist/{Pulse → MarketPulse}/Model/PulseCatalogProductFilters.js +0 -0
  145. /package/dist/{Pulse → MarketPulse}/Model/ReviewMatch.d.ts +0 -0
  146. /package/dist/{Pulse → MarketPulse}/Model/ReviewMatch.js +0 -0
  147. /package/dist/{Pulse → MarketPulse}/Model/ReviewMatchFilters.d.ts +0 -0
  148. /package/dist/{Pulse → MarketPulse}/Model/ReviewMatchFilters.js +0 -0
  149. /package/dist/{Pulse → MarketPulse}/Model/TopCompetitor.d.ts +0 -0
  150. /package/dist/{Pulse → MarketPulse}/Model/TopCompetitor.js +0 -0
  151. /package/dist/{Pulse → MarketPulse}/Model/Vendor.d.ts +0 -0
  152. /package/dist/{Pulse → MarketPulse}/Model/Vendor.js +0 -0
  153. /package/dist/{Pulse → MarketPulse}/Model/VendorProduct.d.ts +0 -0
  154. /package/dist/{Pulse → MarketPulse}/Model/VendorProduct.js +0 -0
  155. /package/dist/{Pulse → MarketPulse}/Model/VendorProductPriceHistoryEntry.d.ts +0 -0
  156. /package/dist/{Pulse → MarketPulse}/Model/VendorProductPriceHistoryEntry.js +0 -0
  157. /package/dist/{Pulse → MarketPulse}/Model/VendorStatus.d.ts +0 -0
  158. /package/dist/{Pulse → MarketPulse}/Model/VendorStatus.js +0 -0
  159. /package/dist/{Pulse → MarketPulse}/Service/CompetitorEndpoint.d.ts +0 -0
  160. /package/dist/{Pulse → MarketPulse}/Service/IndexJobEndpoint.d.ts +0 -0
  161. /package/dist/{Pulse → MarketPulse}/Service/PriceAlertEndpoint.d.ts +0 -0
  162. /package/dist/{Pulse → MarketPulse}/Service/PricingEndpoint.d.ts +0 -0
  163. /package/dist/{Pulse → MarketPulse}/Service/ProductGroupEndpoint.d.ts +0 -0
  164. /package/dist/{Pulse → MarketPulse}/Service/ProductMatchEndpoint.d.ts +0 -0
  165. /package/dist/{Pulse → MarketPulse}/Service/ProductMatchJobEndpoint.d.ts +0 -0
  166. /package/dist/{Pulse → MarketPulse}/Service/PulseCatalogProductEndpoint.d.ts +0 -0
  167. /package/dist/{Pulse → MarketPulse}/Service/PulseStatisticsEndpoint.d.ts +0 -0
  168. /package/dist/{Pulse → MarketPulse}/Service/VendorProductEndpoint.d.ts +0 -0
@@ -1,3 +1,4 @@
1
+ import { path } from '../../Http/Data/Path.js';
1
2
  import { QueryString } from '../../Http/Data/QueryString.js';
2
3
  import { Log } from '../Model/Log.js';
3
4
  import { LogStream } from '../Model/LogStream.js';
@@ -36,12 +37,13 @@ export class LogEndpoint extends Endpoint {
36
37
  const strTags = arrTags.join(',');
37
38
  arrQuery.push('tags=' + strTags);
38
39
  }
39
- const cmd = '/logstreams/' + logQuery.logStreamId.toString() + '/logs/?' + arrQuery.join('&');
40
+ const cmd = path('/logstreams/:logStreamId/logs/', { logStreamId: logQuery.logStreamId.toString() })
41
+ + '?' + arrQuery.join('&');
40
42
  const result = await this.requestCollection(cmd, Log.parse);
41
43
  return result;
42
44
  }
43
45
  async getCursoredLogEntries(logStreamId, pagination, filter) {
44
- const queryString = new QueryString('/logstreams/' + logStreamId.toString() + '/logs');
46
+ const queryString = new QueryString(path('/logstreams/:logStreamId/logs', { logStreamId: logStreamId.toString() }));
45
47
  queryString.addPagination(pagination);
46
48
  if (filter !== null && filter !== undefined) {
47
49
  queryString.set('filter', JSON.stringify(filter));
@@ -51,7 +53,7 @@ export class LogEndpoint extends Endpoint {
51
53
  }
52
54
  async save(log) {
53
55
  try {
54
- const cmd = '/logstreams/' + log.logStream.toString() + '/logs';
56
+ const cmd = path('/logstreams/:logStream/logs', { logStream: log.logStream.toString() });
55
57
  const result = await this.requestObject(cmd, log, Log.parse, 'POST');
56
58
  const updatedLogEntry = result.getData();
57
59
  if (updatedLogEntry === null) {
@@ -66,8 +68,12 @@ export class LogEndpoint extends Endpoint {
66
68
  throw error;
67
69
  }
68
70
  }
69
- async delete(logId) {
70
- const cmd = '/logstreams/:streamId/logs/' + logId;
71
+ /**
72
+ * The stream id was missing here: the path was built with the literal text `:streamId`, so every
73
+ * call requested `/logstreams/:streamId/logs/<id>` and could never have matched the route.
74
+ */
75
+ async delete(logStreamId, logId) {
76
+ const cmd = path('/logstreams/:logStreamId/logs/:logId', { logStreamId, logId });
71
77
  try {
72
78
  const parser = (raw) => ({ deleted: raw.deleted });
73
79
  const result = await this.requestObject(cmd, null, parser, 'DELETE');
@@ -86,7 +92,7 @@ export class LogEndpoint extends Endpoint {
86
92
  }
87
93
  }
88
94
  async clear(logStreamId) {
89
- const cmd = '/logstreams/' + logStreamId.toString() + '/clear';
95
+ const cmd = path('/logstreams/:logStreamId/clear', { logStreamId: logStreamId.toString() });
90
96
  try {
91
97
  const parser = (raw) => ({ cleared: raw.cleared });
92
98
  const result = await this.requestObject(cmd, null, parser, 'POST');
@@ -106,7 +112,7 @@ export class LogEndpoint extends Endpoint {
106
112
  }
107
113
  async getInformation(logStreamId) {
108
114
  try {
109
- const url = '/logstreams/' + logStreamId.toString() + '/info';
115
+ const url = path('/logstreams/:logStreamId/info', { logStreamId: logStreamId.toString() });
110
116
  const result = await this.requestObject(url, null, LogStreamInformation.parse);
111
117
  return result.getData();
112
118
  }
@@ -118,7 +124,7 @@ export class LogEndpoint extends Endpoint {
118
124
  }
119
125
  }
120
126
  async getByProject(projectId, pagination = null) {
121
- const queryString = new QueryString('projects/' + projectId + '/logstreams');
127
+ const queryString = new QueryString(path('projects/:projectId/logstreams', { projectId }));
122
128
  queryString.addPagination(pagination);
123
129
  const parser = (raw) => new LogStream(new LogStreamId(raw.id), raw.name);
124
130
  const result = await this.requestCollection(queryString, parser);
@@ -1,3 +1,4 @@
1
+ import { path } from '../../Http/Data/Path.js';
1
2
  import { QueryString } from '../../Http/Data/QueryString.js';
2
3
  import { Endpoint } from '../../Service/Endpoint.js';
3
4
  import { Competitor } from '../Model/Competitor.js';
@@ -7,17 +8,17 @@ import { Competitor } from '../Model/Competitor.js';
7
8
  */
8
9
  export class CompetitorEndpoint extends Endpoint {
9
10
  async getByCatalog(catalogId, pagination = null) {
10
- const queryString = new QueryString('/pulse/catalogs/' + catalogId.toString() + '/competing-vendors');
11
+ const queryString = new QueryString(path('/pulse/catalogs/:catalogId/competing-vendors', { catalogId: catalogId.toString() }));
11
12
  queryString.addPagination(pagination);
12
13
  return await this.requestCollection(queryString, Competitor.parse);
13
14
  }
14
15
  async getById(competitorId) {
15
- const result = await this.requestObject('/pulse/competing-vendors/' + competitorId, null, Competitor.parse, 'GET');
16
+ const result = await this.requestObject(path('/pulse/competing-vendors/:competitorId', { competitorId }), null, Competitor.parse, 'GET');
16
17
  return result.getData();
17
18
  }
18
19
  /** Start watching a vendor as a competitor of this catalog. */
19
20
  async add(catalogId, vendorId) {
20
- const result = await this.requestObject('/pulse/catalogs/' + catalogId.toString() + '/competing-vendors', { vendor: vendorId }, Competitor.parse, 'POST');
21
+ const result = await this.requestObject(path('/pulse/catalogs/:catalogId/competing-vendors', { catalogId: catalogId.toString() }), { vendor: vendorId }, Competitor.parse, 'POST');
21
22
  return result.getData();
22
23
  }
23
24
  }
@@ -32,5 +32,6 @@ export declare class CrawlJobEndpoint extends Endpoint {
32
32
  markPagesParsed(crawlJobId: string, urls: string[]): Promise<void>;
33
33
  /** Mark pages as failed (terminal, e.g. blocked/unfetchable). */
34
34
  markPagesFailed(crawlJobId: string, urls: string[]): Promise<void>;
35
+ /** @param suffix a literal trailing segment, e.g. `/pages/crawled` — not caller data. */
35
36
  private postUrls;
36
37
  }
@@ -1,3 +1,4 @@
1
+ import { path } from '../../Http/Data/Path.js';
1
2
  import { QueryString } from '../../Http/Data/QueryString.js';
2
3
  import { CrawlJob } from '../Model/CrawlJob.js';
3
4
  import { Endpoint } from '../../Service/Endpoint.js';
@@ -18,7 +19,7 @@ export class CrawlJobEndpoint extends Endpoint {
18
19
  }
19
20
  /** Update a crawl job's status ('started', 'finished', 'cancelled'). */
20
21
  async updateStatus(crawlJobId, status) {
21
- const result = await this.requestObject('/pulse/crawl-jobs/' + crawlJobId, { status }, CrawlJob.parse, 'PATCH');
22
+ const result = await this.requestObject(path('/pulse/crawl-jobs/:crawlJobId', { crawlJobId }), { status }, CrawlJob.parse, 'PATCH');
22
23
  const job = result.getData();
23
24
  if (job === null) {
24
25
  throw new Error('Unable to update crawl job: empty response');
@@ -27,7 +28,7 @@ export class CrawlJobEndpoint extends Endpoint {
27
28
  }
28
29
  /** A vendor's crawl jobs (newest first), each with progress (`total` / `processed`). */
29
30
  async getByVendor(vendorId, pagination = null) {
30
- const queryString = new QueryString('/pulse/vendors/' + vendorId + '/crawl-jobs');
31
+ const queryString = new QueryString(path('/pulse/vendors/:vendorId/crawl-jobs', { vendorId }));
31
32
  queryString.addPagination(pagination);
32
33
  return await this.requestCollection(queryString, CrawlJob.parse);
33
34
  }
@@ -38,13 +39,13 @@ export class CrawlJobEndpoint extends Endpoint {
38
39
  * and returns the jobs of their vendors.
39
40
  */
40
41
  async getByCatalog(catalogId, pagination = null) {
41
- const queryString = new QueryString('/pulse/catalogs/' + catalogId.toString() + '/crawl-jobs');
42
+ const queryString = new QueryString(path('/pulse/catalogs/:catalogId/crawl-jobs', { catalogId: catalogId.toString() }));
42
43
  queryString.addPagination(pagination);
43
44
  return await this.requestCollection(queryString, CrawlJob.parse);
44
45
  }
45
46
  /** The crawl job with this id, or null. */
46
47
  async getById(crawlJobId) {
47
- const result = await this.requestObject('/pulse/crawl-jobs/' + crawlJobId, null, CrawlJob.parse, 'GET');
48
+ const result = await this.requestObject(path('/pulse/crawl-jobs/:crawlJobId', { crawlJobId }), null, CrawlJob.parse, 'GET');
48
49
  return result.getData();
49
50
  }
50
51
  /** Register the pages this crawl will process (idempotent server-side). */
@@ -63,10 +64,11 @@ export class CrawlJobEndpoint extends Endpoint {
63
64
  async markPagesFailed(crawlJobId, urls) {
64
65
  await this.postUrls(crawlJobId, '/pages/failed', urls);
65
66
  }
66
- async postUrls(crawlJobId, path, urls) {
67
+ /** @param suffix a literal trailing segment, e.g. `/pages/crawled` — not caller data. */
68
+ async postUrls(crawlJobId, suffix, urls) {
67
69
  if (urls.length === 0) {
68
70
  return;
69
71
  }
70
- await this.requestObject('/pulse/crawl-jobs/' + crawlJobId + path, { urls }, (raw) => raw, 'POST');
72
+ await this.requestObject(path('/pulse/crawl-jobs/:crawlJobId', { crawlJobId }) + suffix, { urls }, (raw) => raw, 'POST');
71
73
  }
72
74
  }
@@ -1,3 +1,4 @@
1
+ import { path } from '../../Http/Data/Path.js';
1
2
  import { QueryString } from '../../Http/Data/QueryString.js';
2
3
  import { Endpoint } from '../../Service/Endpoint.js';
3
4
  import { IndexJob } from '../Model/IndexJob.js';
@@ -9,23 +10,23 @@ import { VendorStatus } from '../Model/VendorStatus.js';
9
10
  export class IndexJobEndpoint extends Endpoint {
10
11
  /** Index jobs across every competitor of a catalog, newest first. */
11
12
  async getByCatalog(catalogId, pagination = null) {
12
- const queryString = new QueryString('/pulse/catalogs/' + catalogId.toString() + '/index-jobs');
13
+ const queryString = new QueryString(path('/pulse/catalogs/:catalogId/index-jobs', { catalogId: catalogId.toString() }));
13
14
  queryString.addPagination(pagination);
14
15
  return await this.requestCollection(queryString, IndexJob.parse);
15
16
  }
16
17
  /** Index jobs of one competitor. */
17
18
  async getByVendor(catalogId, vendorId, pagination = null) {
18
- const queryString = new QueryString('/pulse/catalogs/' + catalogId.toString() + '/vendors/' + vendorId + '/index-jobs');
19
+ const queryString = new QueryString(path('/pulse/catalogs/:catalogId/vendors/:vendorId/index-jobs', { catalogId: catalogId.toString(), vendorId }));
19
20
  queryString.addPagination(pagination);
20
21
  return await this.requestCollection(queryString, IndexJob.parse);
21
22
  }
22
23
  /** Queue a re-index of a competitor's products, so later matching sees current data. */
23
24
  async requestReindex(catalogId, vendorId) {
24
- await this.requestObject('/pulse/catalogs/' + catalogId.toString() + '/vendors/' + vendorId + '/reindex', {}, (raw) => raw, 'POST');
25
+ await this.requestObject(path('/pulse/catalogs/:catalogId/vendors/:vendorId/reindex', { catalogId: catalogId.toString(), vendorId }), {}, (raw) => raw, 'POST');
25
26
  }
26
27
  /** How fresh a competitor's index and matches are, plus any match job running right now. */
27
28
  async getVendorStatus(catalogId, vendorId) {
28
- const result = await this.requestObject('/pulse/catalogs/' + catalogId.toString() + '/vendors/' + vendorId + '/status', null, VendorStatus.parse, 'GET');
29
+ const result = await this.requestObject(path('/pulse/catalogs/:catalogId/vendors/:vendorId/status', { catalogId: catalogId.toString(), vendorId }), null, VendorStatus.parse, 'GET');
29
30
  return result.getData();
30
31
  }
31
32
  }
@@ -1,3 +1,4 @@
1
+ import { path } from '../../Http/Data/Path.js';
1
2
  import { QueryString } from '../../Http/Data/QueryString.js';
2
3
  import { Endpoint } from '../../Service/Endpoint.js';
3
4
  import { PriceAlertConfig } from '../Model/PriceAlertConfig.js';
@@ -7,27 +8,27 @@ import { PriceAlertEvent } from '../Model/PriceAlertEvent.js';
7
8
  */
8
9
  export class PriceAlertEndpoint extends Endpoint {
9
10
  async getConfigs(catalogId, pagination = null) {
10
- const queryString = new QueryString('/pulse/catalogs/' + catalogId.toString() + '/price-alert-configs');
11
+ const queryString = new QueryString(path('/pulse/catalogs/:catalogId/price-alert-configs', { catalogId: catalogId.toString() }));
11
12
  queryString.addPagination(pagination);
12
13
  return await this.requestCollection(queryString, PriceAlertConfig.parse);
13
14
  }
14
15
  async getConfig(alertConfigId) {
15
- const result = await this.requestObject('/pulse/price-alert-configs/' + alertConfigId, null, PriceAlertConfig.parse, 'GET');
16
+ const result = await this.requestObject(path('/pulse/price-alert-configs/:alertConfigId', { alertConfigId }), null, PriceAlertConfig.parse, 'GET');
16
17
  return result.getData();
17
18
  }
18
19
  async createConfig(catalogId, data) {
19
- const result = await this.requestObject('/pulse/catalogs/' + catalogId.toString() + '/price-alert-configs', data, PriceAlertConfig.parse, 'POST');
20
+ const result = await this.requestObject(path('/pulse/catalogs/:catalogId/price-alert-configs', { catalogId: catalogId.toString() }), data, PriceAlertConfig.parse, 'POST');
20
21
  return result.getData();
21
22
  }
22
23
  async updateConfig(alertConfigId, data) {
23
- const result = await this.requestObject('/pulse/price-alert-configs/' + alertConfigId, data, PriceAlertConfig.parse, 'PATCH');
24
+ const result = await this.requestObject(path('/pulse/price-alert-configs/:alertConfigId', { alertConfigId }), data, PriceAlertConfig.parse, 'PATCH');
24
25
  return result.getData();
25
26
  }
26
27
  async deleteConfig(alertConfigId) {
27
- await this.requestObject('/pulse/price-alert-configs/' + alertConfigId, null, (raw) => raw, 'DELETE');
28
+ await this.requestObject(path('/pulse/price-alert-configs/:alertConfigId', { alertConfigId }), null, (raw) => raw, 'DELETE');
28
29
  }
29
30
  async getEvents(alertConfigId, pagination = null) {
30
- const queryString = new QueryString('/pulse/price-alert-configs/' + alertConfigId + '/events');
31
+ const queryString = new QueryString(path('/pulse/price-alert-configs/:alertConfigId/events', { alertConfigId }));
31
32
  queryString.addPagination(pagination);
32
33
  return await this.requestCollection(queryString, PriceAlertEvent.parse);
33
34
  }
@@ -36,7 +37,7 @@ export class PriceAlertEndpoint extends Endpoint {
36
37
  * when from the session, so the request carries no body.
37
38
  */
38
39
  async acknowledgeEvent(alertEventId) {
39
- const result = await this.requestObject('/pulse/price-alert-events/' + alertEventId, {}, PriceAlertEvent.parse, 'PATCH');
40
+ const result = await this.requestObject(path('/pulse/price-alert-events/:alertEventId', { alertEventId }), {}, PriceAlertEvent.parse, 'PATCH');
40
41
  return result.getData();
41
42
  }
42
43
  }
@@ -1,3 +1,4 @@
1
+ import { path } from '../../Http/Data/Path.js';
1
2
  import { QueryString } from '../../Http/Data/QueryString.js';
2
3
  import { Endpoint } from '../../Service/Endpoint.js';
3
4
  import { PriceSuggestion } from '../Model/PriceSuggestion.js';
@@ -8,28 +9,28 @@ import { PricingRule } from '../Model/PricingRule.js';
8
9
  */
9
10
  export class PricingEndpoint extends Endpoint {
10
11
  async getRules(catalogId, pagination = null) {
11
- const queryString = new QueryString('/pulse/catalogs/' + catalogId.toString() + '/pricing-rules');
12
+ const queryString = new QueryString(path('/pulse/catalogs/:catalogId/pricing-rules', { catalogId: catalogId.toString() }));
12
13
  queryString.addPagination(pagination);
13
14
  return await this.requestCollection(queryString, PricingRule.parse);
14
15
  }
15
16
  async getRule(pricingRuleId) {
16
- const result = await this.requestObject('/pulse/pricing-rules/' + pricingRuleId, null, PricingRule.parse, 'GET');
17
+ const result = await this.requestObject(path('/pulse/pricing-rules/:pricingRuleId', { pricingRuleId }), null, PricingRule.parse, 'GET');
17
18
  return result.getData();
18
19
  }
19
20
  async createRule(catalogId, data) {
20
- const result = await this.requestObject('/pulse/catalogs/' + catalogId.toString() + '/pricing-rules', data, PricingRule.parse, 'POST');
21
+ const result = await this.requestObject(path('/pulse/catalogs/:catalogId/pricing-rules', { catalogId: catalogId.toString() }), data, PricingRule.parse, 'POST');
21
22
  return result.getData();
22
23
  }
23
24
  async updateRule(pricingRuleId, data) {
24
- const result = await this.requestObject('/pulse/pricing-rules/' + pricingRuleId, data, PricingRule.parse, 'PATCH');
25
+ const result = await this.requestObject(path('/pulse/pricing-rules/:pricingRuleId', { pricingRuleId }), data, PricingRule.parse, 'PATCH');
25
26
  return result.getData();
26
27
  }
27
28
  async deleteRule(pricingRuleId) {
28
- await this.requestObject('/pulse/pricing-rules/' + pricingRuleId, null, (raw) => raw, 'DELETE');
29
+ await this.requestObject(path('/pulse/pricing-rules/:pricingRuleId', { pricingRuleId }), null, (raw) => raw, 'DELETE');
29
30
  }
30
31
  /** Price suggestions of a catalog, optionally only those in one status. */
31
32
  async getSuggestions(catalogId, pagination = null, status = null) {
32
- const queryString = new QueryString('/pulse/catalogs/' + catalogId.toString() + '/price-suggestions');
33
+ const queryString = new QueryString(path('/pulse/catalogs/:catalogId/price-suggestions', { catalogId: catalogId.toString() }));
33
34
  if (status !== null) {
34
35
  queryString.set('status', status);
35
36
  }
@@ -37,7 +38,7 @@ export class PricingEndpoint extends Endpoint {
37
38
  return await this.requestCollection(queryString, PriceSuggestion.parse);
38
39
  }
39
40
  async getSuggestion(priceSuggestionId) {
40
- const result = await this.requestObject('/pulse/price-suggestions/' + priceSuggestionId, null, PriceSuggestion.parse, 'GET');
41
+ const result = await this.requestObject(path('/pulse/price-suggestions/:priceSuggestionId', { priceSuggestionId }), null, PriceSuggestion.parse, 'GET');
41
42
  return result.getData();
42
43
  }
43
44
  /**
@@ -45,7 +46,7 @@ export class PricingEndpoint extends Endpoint {
45
46
  * itself is done by a flow, which sets `appliedAt`.
46
47
  */
47
48
  async reviewSuggestion(priceSuggestionId, status) {
48
- const result = await this.requestObject('/pulse/price-suggestions/' + priceSuggestionId, { status }, PriceSuggestion.parse, 'PATCH');
49
+ const result = await this.requestObject(path('/pulse/price-suggestions/:priceSuggestionId', { priceSuggestionId }), { status }, PriceSuggestion.parse, 'PATCH');
49
50
  return result.getData();
50
51
  }
51
52
  }
@@ -1,19 +1,20 @@
1
+ import { path } from '../../Http/Data/Path.js';
1
2
  import { QueryString } from '../../Http/Data/QueryString.js';
2
3
  import { Endpoint } from '../../Service/Endpoint.js';
3
4
  import { ProductGroup } from '../Model/ProductGroup.js';
4
5
  /** Product groups — `/pulse/catalogs/:catalogId/product-groups`. */
5
6
  export class ProductGroupEndpoint extends Endpoint {
6
7
  async getByCatalog(catalogId, pagination = null) {
7
- const queryString = new QueryString('/pulse/catalogs/' + catalogId.toString() + '/product-groups');
8
+ const queryString = new QueryString(path('/pulse/catalogs/:catalogId/product-groups', { catalogId: catalogId.toString() }));
8
9
  queryString.addPagination(pagination);
9
10
  return await this.requestCollection(queryString, ProductGroup.parse);
10
11
  }
11
12
  async getById(productGroupId) {
12
- const result = await this.requestObject('/pulse/product-groups/' + productGroupId, null, ProductGroup.parse, 'GET');
13
+ const result = await this.requestObject(path('/pulse/product-groups/:productGroupId', { productGroupId }), null, ProductGroup.parse, 'GET');
13
14
  return result.getData();
14
15
  }
15
16
  async create(catalogId, data) {
16
- const result = await this.requestObject('/pulse/catalogs/' + catalogId.toString() + '/product-groups', data, ProductGroup.parse, 'POST');
17
+ const result = await this.requestObject(path('/pulse/catalogs/:catalogId/product-groups', { catalogId: catalogId.toString() }), data, ProductGroup.parse, 'POST');
17
18
  return result.getData();
18
19
  }
19
20
  }
@@ -1,3 +1,4 @@
1
+ import { path } from '../../Http/Data/Path.js';
1
2
  import { QueryString } from '../../Http/Data/QueryString.js';
2
3
  import { Endpoint } from '../../Service/Endpoint.js';
3
4
  import { ProductMatch } from '../Model/ProductMatch.js';
@@ -9,7 +10,7 @@ import { ReviewMatch } from '../Model/ReviewMatch.js';
9
10
  export class ProductMatchEndpoint extends Endpoint {
10
11
  /** The review queue of a catalog; pending matches unless `statuses` says otherwise. */
11
12
  async getForReview(catalogId, pagination = null, filters = {}) {
12
- const queryString = new QueryString('/pulse/catalogs/' + catalogId.toString() + '/matches');
13
+ const queryString = new QueryString(path('/pulse/catalogs/:catalogId/matches', { catalogId: catalogId.toString() }));
13
14
  queryString.set('status', (filters.statuses ?? ['pending']).join(','));
14
15
  if (filters.competitor) {
15
16
  queryString.set('competitor', filters.competitor);
@@ -25,20 +26,20 @@ export class ProductMatchEndpoint extends Endpoint {
25
26
  }
26
27
  /** The match record, or null. */
27
28
  async getById(matchId) {
28
- const result = await this.requestObject('/pulse/matches/' + matchId, null, ProductMatch.parse, 'GET');
29
+ const result = await this.requestObject(path('/pulse/matches/:matchId', { matchId }), null, ProductMatch.parse, 'GET');
29
30
  return result.getData();
30
31
  }
31
32
  /** Confirm a match. `note` records why, for the reviewer's own audit trail. */
32
33
  async accept(matchId, note = null) {
33
- await this.requestObject('/pulse/matches/' + matchId + '/accept', note === null ? {} : { note }, (raw) => raw, 'POST');
34
+ await this.requestObject(path('/pulse/matches/:matchId/accept', { matchId }), note === null ? {} : { note }, (raw) => raw, 'POST');
34
35
  }
35
36
  /** Reject a match, so it stops counting towards the competitor's price index. */
36
37
  async decline(matchId, note = null) {
37
- await this.requestObject('/pulse/matches/' + matchId + '/decline', note === null ? {} : { note }, (raw) => raw, 'POST');
38
+ await this.requestObject(path('/pulse/matches/:matchId/decline', { matchId }), note === null ? {} : { note }, (raw) => raw, 'POST');
38
39
  }
39
40
  /** How many matches were discovered and reviewed over time, optionally for one competitor. */
40
41
  async getHistory(catalogId, competitor = null, interval = 'day') {
41
- const queryString = new QueryString('/pulse/catalogs/' + catalogId.toString() + '/matches/history');
42
+ const queryString = new QueryString(path('/pulse/catalogs/:catalogId/matches/history', { catalogId: catalogId.toString() }));
42
43
  queryString.set('interval', interval);
43
44
  if (competitor !== null) {
44
45
  queryString.set('competitor', competitor);
@@ -1,3 +1,4 @@
1
+ import { path } from '../../Http/Data/Path.js';
1
2
  import { QueryString } from '../../Http/Data/QueryString.js';
2
3
  import { ProductMatchJob } from '../Model/ProductMatchJob.js';
3
4
  import { Endpoint } from '../../Service/Endpoint.js';
@@ -8,23 +9,23 @@ import { Endpoint } from '../../Service/Endpoint.js';
8
9
  export class ProductMatchJobEndpoint extends Endpoint {
9
10
  /** Every match job of a catalog, newest first. */
10
11
  async getByCatalog(catalogId, pagination = null) {
11
- const queryString = new QueryString('/pulse/catalogs/' + catalogId.toString() + '/match-jobs');
12
+ const queryString = new QueryString(path('/pulse/catalogs/:catalogId/match-jobs', { catalogId: catalogId.toString() }));
12
13
  queryString.addPagination(pagination);
13
14
  return await this.requestCollection(queryString, ProductMatchJob.parse);
14
15
  }
15
16
  /** The match jobs of one of the catalog's competitors. */
16
17
  async getByVendor(catalogId, vendorId, pagination = null) {
17
- const queryString = new QueryString('/pulse/catalogs/' + catalogId.toString() + '/vendors/' + vendorId + '/match-jobs');
18
+ const queryString = new QueryString(path('/pulse/catalogs/:catalogId/vendors/:vendorId/match-jobs', { catalogId: catalogId.toString(), vendorId }));
18
19
  queryString.addPagination(pagination);
19
20
  return await this.requestCollection(queryString, ProductMatchJob.parse);
20
21
  }
21
22
  /** Queue a matching run of the catalog against one competitor. */
22
23
  async requestMatching(catalogId, vendorId) {
23
- await this.requestObject('/pulse/catalogs/' + catalogId.toString() + '/vendors/' + vendorId + '/match', {}, (raw) => raw, 'POST');
24
+ await this.requestObject(path('/pulse/catalogs/:catalogId/vendors/:vendorId/match', { catalogId: catalogId.toString(), vendorId }), {}, (raw) => raw, 'POST');
24
25
  }
25
26
  /** The match job with this id, or null. */
26
27
  async getById(productMatchJobId) {
27
- const result = await this.requestObject('/pulse/match-jobs/' + productMatchJobId, null, ProductMatchJob.parse, 'GET');
28
+ const result = await this.requestObject(path('/pulse/match-jobs/:productMatchJobId', { productMatchJobId }), null, ProductMatchJob.parse, 'GET');
28
29
  return result.getData();
29
30
  }
30
31
  }
@@ -1,3 +1,4 @@
1
+ import { path } from '../../Http/Data/Path.js';
1
2
  import { QueryString } from '../../Http/Data/QueryString.js';
2
3
  import { Endpoint } from '../../Service/Endpoint.js';
3
4
  import { CatalogProductWithMatches } from '../Model/CatalogProductWithMatches.js';
@@ -13,7 +14,7 @@ export class PulseCatalogProductEndpoint extends Endpoint {
13
14
  * anything the simple filters cannot express.
14
15
  */
15
16
  async getProducts(catalogId, pagination = null, filters = {}, filter = null) {
16
- const queryString = new QueryString('/pulse/catalogs/' + catalogId.toString() + '/products');
17
+ const queryString = new QueryString(path('/pulse/catalogs/:catalogId/products', { catalogId: catalogId.toString() }));
17
18
  queryString.set('expand', ['matches.vendor']);
18
19
  if (filters.brand) {
19
20
  queryString.set('brand', filters.brand);
@@ -39,7 +40,7 @@ export class PulseCatalogProductEndpoint extends Endpoint {
39
40
  return await this.requestCollection(queryString, CatalogProductWithMatches.parse);
40
41
  }
41
42
  async getFilterOptions(catalogId) {
42
- const result = await this.requestObject('/pulse/catalogs/' + catalogId.toString() + '/filter-options', null, (raw) => ({
43
+ const result = await this.requestObject(path('/pulse/catalogs/:catalogId/filter-options', { catalogId: catalogId.toString() }), null, (raw) => ({
43
44
  brands: raw.brands ?? [],
44
45
  categories: raw.categories ?? [],
45
46
  productGroups: raw.product_groups ?? [],
@@ -49,6 +50,6 @@ export class PulseCatalogProductEndpoint extends Endpoint {
49
50
  }
50
51
  /** Recalculate the catalog's cached statistics (price index, match counts, segments). */
51
52
  async recomputeStatistics(catalogId) {
52
- await this.requestObject('/pulse/catalogs/' + catalogId.toString() + '/recompute-stats', {}, (raw) => raw, 'POST');
53
+ await this.requestObject(path('/pulse/catalogs/:catalogId/recompute-stats', { catalogId: catalogId.toString() }), {}, (raw) => raw, 'POST');
53
54
  }
54
55
  }
@@ -1,3 +1,4 @@
1
+ import { path } from '../../Http/Data/Path.js';
1
2
  import { QueryString } from '../../Http/Data/QueryString.js';
2
3
  import { Endpoint } from '../../Service/Endpoint.js';
3
4
  import { PriceIndexSnapshotEntry } from '../Model/PriceIndexSnapshotEntry.js';
@@ -9,7 +10,7 @@ import { TopCompetitor } from '../Model/TopCompetitor.js';
9
10
  export class PulseStatisticsEndpoint extends Endpoint {
10
11
  /** Headline figures (products tracked, matches, competitors …) against the previous period. */
11
12
  async getAccountSummary(catalogId) {
12
- return await this.requestCollection('/pulse/catalogs/' + catalogId.toString() + '/statistics/account-summary', (raw) => ({
13
+ return await this.requestCollection(path('/pulse/catalogs/:catalogId/statistics/account-summary', { catalogId: catalogId.toString() }), (raw) => ({
13
14
  id: raw.id,
14
15
  title: raw.title,
15
16
  currentAmount: raw.current_amount ?? 0,
@@ -18,7 +19,7 @@ export class PulseStatisticsEndpoint extends Endpoint {
18
19
  }
19
20
  /** Distribution of the catalog's products across price or profit segments. */
20
21
  async getProductSegments(catalogId, type = null) {
21
- const queryString = new QueryString('/pulse/catalogs/' + catalogId.toString() + '/statistics/product-segments');
22
+ const queryString = new QueryString(path('/pulse/catalogs/:catalogId/statistics/product-segments', { catalogId: catalogId.toString() }));
22
23
  if (type !== null) {
23
24
  queryString.set('type', type);
24
25
  }
@@ -33,7 +34,7 @@ export class PulseStatisticsEndpoint extends Endpoint {
33
34
  * the comparison against the previous period spans.
34
35
  */
35
36
  async getTopCompetitors(catalogId, limit = null, period = null) {
36
- const queryString = new QueryString('/pulse/catalogs/' + catalogId.toString() + '/statistics/top-competitors');
37
+ const queryString = new QueryString(path('/pulse/catalogs/:catalogId/statistics/top-competitors', { catalogId: catalogId.toString() }));
37
38
  if (limit !== null) {
38
39
  queryString.set('limit', limit);
39
40
  }
@@ -47,7 +48,7 @@ export class PulseStatisticsEndpoint extends Endpoint {
47
48
  * optionally a product group to scope to and a date range (`YYYY-MM-DD`).
48
49
  */
49
50
  async getPriceIndexHistory(catalogId, competitorIds = [], options = {}) {
50
- const queryString = new QueryString('/pulse/catalogs/' + catalogId.toString() + '/statistics/price-index-history');
51
+ const queryString = new QueryString(path('/pulse/catalogs/:catalogId/statistics/price-index-history', { catalogId: catalogId.toString() }));
51
52
  if (competitorIds.length > 0) {
52
53
  queryString.set('competitor', competitorIds.join(','));
53
54
  }
@@ -1,3 +1,4 @@
1
+ import { path } from '../../Http/Data/Path.js';
1
2
  import { QueryString } from '../../Http/Data/QueryString.js';
2
3
  import { CompetingVendorProduct } from '../Model/CompetingVendorProduct.js';
3
4
  import { VendorProduct } from '../Model/VendorProduct.js';
@@ -10,7 +11,7 @@ import { Endpoint } from '../../Service/Endpoint.js';
10
11
  export class VendorProductEndpoint extends Endpoint {
11
12
  /** The product with this identifier for the vendor, or null. */
12
13
  async getByIdentifier(vendorId, identifier) {
13
- const result = await this.requestCollection('/pulse/vendors/' + vendorId + '/products?identifier=' + encodeURIComponent(identifier), VendorProduct.parse);
14
+ const result = await this.requestCollection(path('/pulse/vendors/:vendorId/products', { vendorId }) + '?identifier=' + encodeURIComponent(identifier), VendorProduct.parse);
14
15
  const products = result.getData();
15
16
  return products.length > 0 ? products[0] : null;
16
17
  }
@@ -19,18 +20,18 @@ export class VendorProductEndpoint extends Endpoint {
19
20
  * Same products as {@link getByVendor}, read through the competitor, so `competitorId` is set.
20
21
  */
21
22
  async getByCompetitor(competitorId, pagination = null) {
22
- const queryString = new QueryString('/pulse/competing-vendors/' + competitorId + '/products');
23
+ const queryString = new QueryString(path('/pulse/competing-vendors/:competitorId/products', { competitorId }));
23
24
  queryString.addPagination(pagination);
24
25
  return await this.requestCollection(queryString, CompetingVendorProduct.parse);
25
26
  }
26
27
  /** A single competitor product — `/pulse/competing-vendors/products/:id`. */
27
28
  async getCompetitorProductById(competingVendorProductId) {
28
- const result = await this.requestObject('/pulse/competing-vendors/products/' + competingVendorProductId, null, CompetingVendorProduct.parse, 'GET');
29
+ const result = await this.requestObject(path('/pulse/competing-vendors/products/:competingVendorProductId', { competingVendorProductId }), null, CompetingVendorProduct.parse, 'GET');
29
30
  return result.getData();
30
31
  }
31
32
  /** A vendor's products. */
32
33
  async getByVendor(vendorId, pagination = null) {
33
- const queryString = new QueryString('/pulse/vendors/' + vendorId + '/products');
34
+ const queryString = new QueryString(path('/pulse/vendors/:vendorId/products', { vendorId }));
34
35
  queryString.addPagination(pagination);
35
36
  return await this.requestCollection(queryString, VendorProduct.parse);
36
37
  }
@@ -39,7 +40,7 @@ export class VendorProductEndpoint extends Endpoint {
39
40
  * entries (the API defaults to 365).
40
41
  */
41
42
  async getPriceHistory(vendorProductId, limit = null) {
42
- const queryString = new QueryString('/pulse/vendor-products/' + vendorProductId + '/price-history');
43
+ const queryString = new QueryString(path('/pulse/vendor-products/:vendorProductId/price-history', { vendorProductId }));
43
44
  if (limit !== null) {
44
45
  queryString.set('limit', limit.toString());
45
46
  }
@@ -63,7 +64,7 @@ export class VendorProductEndpoint extends Endpoint {
63
64
  isInStock: product.isInStock,
64
65
  properties: product.properties,
65
66
  };
66
- const result = await this.requestObject('/pulse/vendors/' + product.vendorId + '/products', body, VendorProduct.parse, 'POST');
67
+ const result = await this.requestObject(path('/pulse/vendors/:vendorId/products', { vendorId: product.vendorId }), body, VendorProduct.parse, 'POST');
67
68
  return result.getData() ?? product;
68
69
  }
69
70
  /** Update the mutable fields of an existing vendor product (JSON-patch style, per the API). */
@@ -79,6 +80,9 @@ export class VendorProductEndpoint extends Endpoint {
79
80
  { op: 'add', path: 'image', value: product.image },
80
81
  { op: 'add', path: 'properties', value: product.properties },
81
82
  ];
82
- await this.requestObject('/pulse/vendors/' + product.vendorId + '/products/' + product.id, operations, (raw) => raw, 'PATCH');
83
+ if (product.id === null) {
84
+ throw new Error('Unable to update vendor product: the product has no id. Save it first.');
85
+ }
86
+ await this.requestObject(path('/pulse/vendors/:vendorId/products/:id', { vendorId: product.vendorId, id: product.id }), operations, (raw) => raw, 'PATCH');
83
87
  }
84
88
  }
@@ -1,3 +1,4 @@
1
+ import { path } from '../Http/Data/Path.js';
1
2
  import { QueryString } from '../Http/Data/QueryString.js';
2
3
  import { UserAccessToken } from '../Model/AccessToken/UserAccessToken.js';
3
4
  import { Endpoint } from './Endpoint.js';
@@ -43,7 +44,7 @@ export class AccessTokenEndpoint extends Endpoint {
43
44
  }
44
45
  async update(tokenId, name) {
45
46
  try {
46
- const url = '/access-tokens/' + tokenId;
47
+ const url = path('/access-tokens/:tokenId', { tokenId });
47
48
  const result = await this.requestObject(url, {
48
49
  name,
49
50
  }, UserAccessToken.parse, 'POST');
@@ -62,7 +63,7 @@ export class AccessTokenEndpoint extends Endpoint {
62
63
  }
63
64
  async revoke(tokenId) {
64
65
  try {
65
- const url = '/access-tokens/' + tokenId;
66
+ const url = path('/access-tokens/:tokenId', { tokenId });
66
67
  const parser = (raw) => ({ revoked: raw.revoked });
67
68
  const result = await this.requestObject(url, null, parser, 'DELETE');
68
69
  const res = result.getData();