@rankwrangler/http-client 0.6.0 → 0.8.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.
package/README.md CHANGED
@@ -1,77 +1,63 @@
1
1
  # @rankwrangler/http-client
2
2
 
3
- Typed tRPC client for the RankWrangler public API.
4
-
5
- ## Install
3
+ Typed tRPC client for the RankWrangler public agent API.
6
4
 
7
5
  ```bash
8
6
  npm install @rankwrangler/http-client
9
7
  ```
10
8
 
11
- ## Usage
12
-
13
9
  ```ts
14
10
  import { createRankWranglerClient } from '@rankwrangler/http-client';
15
11
 
16
12
  const client = createRankWranglerClient({
17
- baseUrl: 'https://rankwrangler.merchbase.co',
18
- apiKey: 'rrk_...'
13
+ baseUrl: 'https://rankwrangler.merchbase.co',
14
+ apiKey: process.env.MERCHBASE_API_KEY,
15
+ });
16
+
17
+ const product = await client.product.get.mutate({
18
+ marketplaceId: 'ATVPDKIKX0DER',
19
+ asin: 'B0DV53VS61',
20
+ });
21
+
22
+ const search = await client.product.search.mutate({
23
+ term: 'retro gardening shirt',
19
24
  });
20
25
 
21
- const product = await client.getProductInfo.mutate({
22
- marketplaceId: 'ATVPDKIKX0DER',
23
- asin: 'B0DV53VS61'
26
+ const history = await client.product.history.mutate({
27
+ marketplaceId: 'ATVPDKIKX0DER',
28
+ asin: 'B0DV53VS61',
29
+ metrics: ['salesRank', 'price'],
30
+ bucket: 'week',
31
+ });
32
+
33
+ const keywords = await client.keyword.search.query({
34
+ text: 'retro gardening',
24
35
  });
25
36
  ```
26
37
 
27
- The client is scoped to the public surface (`api.public.*`) so it stays aligned with CLI usage.
38
+ The client is scoped to the public surface (`api.public.*`). It exposes Product
39
+ `get/search/history` and keyword `get/search/history`; it does not expose Catalog, Operation,
40
+ polling procedures. Product `get` and `history`, plus keyword reads, expose no refresh controls;
41
+ Product search retains its separate search contract. Product `get` returns the provider-neutral
42
+ current Product shape; Product `history` returns compact rank/price series. `NOT_FOUND` and retryable
43
+ `TIMEOUT` errors are preserved from tRPC, with retry hints on temporary unavailability.
28
44
 
29
45
  ## Types
30
46
 
31
47
  ```ts
32
48
  import type { PublicRouterInputs, PublicRouterOutputs } from '@rankwrangler/http-client';
33
49
 
34
- type GetProductInput = PublicRouterInputs['getProductInfo'];
35
- type GetProductOutput = PublicRouterOutputs['getProductInfo'];
50
+ type ProductGetInput = PublicRouterInputs['product']['get'];
51
+ type ProductSearchOutput = PublicRouterOutputs['product']['search'];
52
+ type KeywordHistoryOutput = PublicRouterOutputs['keyword']['history'];
36
53
  ```
37
54
 
38
- ## Maintenance
39
-
40
- When the public router changes, regenerate the bundled router types:
55
+ When the public router changes, regenerate and build the declarations:
41
56
 
42
57
  ```bash
43
58
  bun run http-client:types
44
- ```
45
-
46
- Build the package before publishing:
47
-
48
- ```bash
49
59
  bun run http-client:build
50
60
  ```
51
61
 
52
- ## Publish
53
-
54
- From `packages/http-client`:
55
-
56
- ```bash
57
- node ../../scripts/release/with-npm-token.mjs npm whoami --userconfig ../../.npmrc
58
- node ../../scripts/release/with-npm-token.mjs npm publish --access public --userconfig ../../.npmrc
59
- ```
60
-
61
- On macOS, the helper reads `NPM_TOKEN` from the environment first and otherwise falls back to the
62
- Keychain item `rankwrangler-npm-token` for account `$USER`.
63
-
64
- Before publishing:
65
-
66
- 1. Run `bun run release:bump <patch|minor|major|X.Y.Z>` from repo root.
67
- 2. Run `bun install` from repo root.
68
- 3. Run `bun run release:collect-changelog-context`, then draft `CHANGELOG.md` entry.
69
- 4. Run `bun run release:check`.
70
- 5. Run `bun run http-client:build` from repo root.
71
- 6. Run `npm pack --dry-run` from `packages/http-client`.
72
-
73
- ## Versioning
74
-
75
- - App releases and npm package versions are synchronized to the same `X.Y.Z`.
76
- - `CHANGELOG.md` uses `vX.Y.Z`; package files use `X.Y.Z`.
77
- - Canonical process lives in `docs/release-runbook.md`.
62
+ See the [HTTP client reference](../../docs/reference/http-client.md) for transport options and
63
+ release workflow.
@@ -1,111 +1,425 @@
1
1
  // Generated by dts-bundle-generator v9.5.1
2
2
 
3
- export interface LicenseUsageData {
4
- id: string;
5
- email: string;
6
- usage: number;
7
- usageLimit: number;
8
- }
3
+ declare const rankwranglerServiceAccounts: import("drizzle-orm/pg-core").PgTableWithColumns<{
4
+ name: "rankwrangler_service_accounts";
5
+ schema: undefined;
6
+ columns: {
7
+ id: import("drizzle-orm/pg-core").PgColumn<{
8
+ name: "id";
9
+ tableName: "rankwrangler_service_accounts";
10
+ dataType: "string";
11
+ columnType: "PgUUID";
12
+ data: string;
13
+ driverParam: string;
14
+ notNull: true;
15
+ hasDefault: true;
16
+ isPrimaryKey: true;
17
+ isAutoincrement: false;
18
+ hasRuntimeDefault: false;
19
+ enumValues: undefined;
20
+ baseColumn: never;
21
+ identity: undefined;
22
+ generated: undefined;
23
+ }, {}, {}>;
24
+ service: import("drizzle-orm/pg-core").PgColumn<{
25
+ name: "service";
26
+ tableName: "rankwrangler_service_accounts";
27
+ dataType: "string";
28
+ columnType: "PgText";
29
+ data: string;
30
+ driverParam: string;
31
+ notNull: true;
32
+ hasDefault: true;
33
+ isPrimaryKey: false;
34
+ isAutoincrement: false;
35
+ hasRuntimeDefault: false;
36
+ enumValues: [
37
+ string,
38
+ ...string[]
39
+ ];
40
+ baseColumn: never;
41
+ identity: undefined;
42
+ generated: undefined;
43
+ }, {}, {}>;
44
+ merchbaseUserId: import("drizzle-orm/pg-core").PgColumn<{
45
+ name: "merchbase_user_id";
46
+ tableName: "rankwrangler_service_accounts";
47
+ dataType: "string";
48
+ columnType: "PgText";
49
+ data: string;
50
+ driverParam: string;
51
+ notNull: false;
52
+ hasDefault: false;
53
+ isPrimaryKey: false;
54
+ isAutoincrement: false;
55
+ hasRuntimeDefault: false;
56
+ enumValues: [
57
+ string,
58
+ ...string[]
59
+ ];
60
+ baseColumn: never;
61
+ identity: undefined;
62
+ generated: undefined;
63
+ }, {}, {}>;
64
+ createdAt: import("drizzle-orm/pg-core").PgColumn<{
65
+ name: "created_at";
66
+ tableName: "rankwrangler_service_accounts";
67
+ dataType: "date";
68
+ columnType: "PgTimestamp";
69
+ data: Date;
70
+ driverParam: string;
71
+ notNull: true;
72
+ hasDefault: true;
73
+ isPrimaryKey: false;
74
+ isAutoincrement: false;
75
+ hasRuntimeDefault: false;
76
+ enumValues: undefined;
77
+ baseColumn: never;
78
+ identity: undefined;
79
+ generated: undefined;
80
+ }, {}, {}>;
81
+ updatedAt: import("drizzle-orm/pg-core").PgColumn<{
82
+ name: "updated_at";
83
+ tableName: "rankwrangler_service_accounts";
84
+ dataType: "date";
85
+ columnType: "PgTimestamp";
86
+ data: Date;
87
+ driverParam: string;
88
+ notNull: true;
89
+ hasDefault: true;
90
+ isPrimaryKey: false;
91
+ isAutoincrement: false;
92
+ hasRuntimeDefault: false;
93
+ enumValues: undefined;
94
+ baseColumn: never;
95
+ identity: undefined;
96
+ generated: undefined;
97
+ }, {}, {}>;
98
+ lastUsedAt: import("drizzle-orm/pg-core").PgColumn<{
99
+ name: "last_used_at";
100
+ tableName: "rankwrangler_service_accounts";
101
+ dataType: "date";
102
+ columnType: "PgTimestamp";
103
+ data: Date;
104
+ driverParam: string;
105
+ notNull: false;
106
+ hasDefault: false;
107
+ isPrimaryKey: false;
108
+ isAutoincrement: false;
109
+ hasRuntimeDefault: false;
110
+ enumValues: undefined;
111
+ baseColumn: never;
112
+ identity: undefined;
113
+ generated: undefined;
114
+ }, {}, {}>;
115
+ usageToday: import("drizzle-orm/pg-core").PgColumn<{
116
+ name: "usage_today";
117
+ tableName: "rankwrangler_service_accounts";
118
+ dataType: "number";
119
+ columnType: "PgInteger";
120
+ data: number;
121
+ driverParam: string | number;
122
+ notNull: true;
123
+ hasDefault: true;
124
+ isPrimaryKey: false;
125
+ isAutoincrement: false;
126
+ hasRuntimeDefault: false;
127
+ enumValues: undefined;
128
+ baseColumn: never;
129
+ identity: undefined;
130
+ generated: undefined;
131
+ }, {}, {}>;
132
+ usageCount: import("drizzle-orm/pg-core").PgColumn<{
133
+ name: "usage_count";
134
+ tableName: "rankwrangler_service_accounts";
135
+ dataType: "number";
136
+ columnType: "PgInteger";
137
+ data: number;
138
+ driverParam: string | number;
139
+ notNull: true;
140
+ hasDefault: true;
141
+ isPrimaryKey: false;
142
+ isAutoincrement: false;
143
+ hasRuntimeDefault: false;
144
+ enumValues: undefined;
145
+ baseColumn: never;
146
+ identity: undefined;
147
+ generated: undefined;
148
+ }, {}, {}>;
149
+ usageLimit: import("drizzle-orm/pg-core").PgColumn<{
150
+ name: "usage_limit";
151
+ tableName: "rankwrangler_service_accounts";
152
+ dataType: "number";
153
+ columnType: "PgInteger";
154
+ data: number;
155
+ driverParam: string | number;
156
+ notNull: true;
157
+ hasDefault: true;
158
+ isPrimaryKey: false;
159
+ isAutoincrement: false;
160
+ hasRuntimeDefault: false;
161
+ enumValues: undefined;
162
+ baseColumn: never;
163
+ identity: undefined;
164
+ generated: undefined;
165
+ }, {}, {}>;
166
+ lastResetAt: import("drizzle-orm/pg-core").PgColumn<{
167
+ name: "last_reset_at";
168
+ tableName: "rankwrangler_service_accounts";
169
+ dataType: "date";
170
+ columnType: "PgTimestamp";
171
+ data: Date;
172
+ driverParam: string;
173
+ notNull: true;
174
+ hasDefault: true;
175
+ isPrimaryKey: false;
176
+ isAutoincrement: false;
177
+ hasRuntimeDefault: false;
178
+ enumValues: undefined;
179
+ baseColumn: never;
180
+ identity: undefined;
181
+ generated: undefined;
182
+ }, {}, {}>;
183
+ };
184
+ dialect: "pg";
185
+ }>;
186
+ export type RankWranglerServicePrincipal = Omit<typeof rankwranglerServiceAccounts.$inferSelect, "merchbaseUserId"> & {
187
+ merchbaseUserId: string;
188
+ };
9
189
  export interface ClerkUser {
10
190
  sub: string;
11
191
  email?: string;
12
192
  }
13
- declare const productHistoryBuckets: readonly [
14
- "auto",
15
- "day",
16
- "week",
17
- "month"
193
+ export type CredentialKind = "api_key" | "oauth" | "session";
194
+ export interface ContextRequest {
195
+ headers: {
196
+ authorization?: string;
197
+ host?: string;
198
+ };
199
+ }
200
+ declare const TOP_SEARCH_TERMS_REPORT_PERIODS: readonly [
201
+ "DAY",
202
+ "WEEK"
18
203
  ];
19
- export type ProductHistoryBucket = (typeof productHistoryBuckets)[number];
20
- export type ResolvedHistoryBucket = Exclude<ProductHistoryBucket, "auto">;
21
- export type HistoryBucketTuple = [
22
- string,
23
- number | null
204
+ declare const TOP_SEARCH_TERMS_REFRESH_TRIGGERS: readonly [
205
+ "requested",
206
+ "automatic"
24
207
  ];
25
- export type HistoryBucketSummary = {
26
- first: number | null;
27
- latest: number | null;
28
- min: number | null;
29
- max: number | null;
30
- count: number;
31
- firstBucketAt: string | null;
32
- latestBucketAt: string | null;
208
+ export type TopSearchTermsReportPeriod = (typeof TOP_SEARCH_TERMS_REPORT_PERIODS)[number];
209
+ export type TopSearchTermsRefreshTrigger = (typeof TOP_SEARCH_TERMS_REFRESH_TRIGGERS)[number];
210
+ export type SearchTermsTrendDelta = {
211
+ rankDelta: number | null;
212
+ clickShareDelta: number | null;
213
+ conversionShareDelta: number | null;
33
214
  };
34
- export type AgentHistorySeries = {
35
- bsr?: {
36
- unit: "rank";
37
- category: {
38
- id: number;
39
- name: string | null;
40
- } | null;
41
- buckets: HistoryBucketTuple[];
42
- summary: HistoryBucketSummary;
215
+ export type SearchTermsTrendDeltas = {
216
+ d1: SearchTermsTrendDelta;
217
+ d7: SearchTermsTrendDelta;
218
+ d30: SearchTermsTrendDelta;
219
+ };
220
+ export interface KeywordEvidence {
221
+ searchFrequencyRank: number;
222
+ clickShareTop3: number;
223
+ conversionShareTop3: number;
224
+ topRowsCount: number;
225
+ isMerchRelevant: boolean;
226
+ merchReason: string;
227
+ }
228
+ export interface KeywordCurrent {
229
+ keyword: string;
230
+ marketplaceId: string;
231
+ reportPeriod: TopSearchTermsReportPeriod;
232
+ dataStartDate: string;
233
+ dataEndDate: string;
234
+ observedDate: string;
235
+ fetchedAt: string;
236
+ trigger: TopSearchTermsRefreshTrigger;
237
+ evidence: KeywordEvidence;
238
+ }
239
+ export interface KeywordSearchItem extends KeywordEvidence {
240
+ keyword: string;
241
+ observedDate: string;
242
+ trigger: TopSearchTermsRefreshTrigger;
243
+ }
244
+ export interface KeywordSearchSummary {
245
+ marketplaceId: string;
246
+ reportPeriod: TopSearchTermsReportPeriod;
247
+ dataStartDate: string | null;
248
+ dataEndDate: string | null;
249
+ observedDate: string | null;
250
+ fetchedAt: string | null;
251
+ totalFiltered: number;
252
+ }
253
+ export interface KeywordSearchResponse {
254
+ status: "ready" | "empty";
255
+ items: KeywordSearchItem[];
256
+ nextCursor: number | null;
257
+ summary: KeywordSearchSummary;
258
+ }
259
+ export interface KeywordHistoryPoint {
260
+ observedDate: string;
261
+ searchFrequencyRank: number;
262
+ clickShareTop3: number;
263
+ conversionShareTop3: number;
264
+ trigger: TopSearchTermsRefreshTrigger;
265
+ }
266
+ export interface KeywordHistoryResponse {
267
+ keyword: string;
268
+ marketplaceId: string;
269
+ reportPeriod: TopSearchTermsReportPeriod;
270
+ rangeDays: number;
271
+ status: "ready" | "empty";
272
+ latestObservedDate: string | null;
273
+ points: KeywordHistoryPoint[];
274
+ deltas: SearchTermsTrendDeltas;
275
+ }
276
+ export interface Product {
277
+ marketplaceId: string;
278
+ asin: string;
279
+ listing: {
280
+ title: string | null;
281
+ brand: string | null;
282
+ firstAvailableAt: string | null;
283
+ bulletPoints: string[];
284
+ thumbnail: {
285
+ status: "available";
286
+ url: string;
287
+ } | {
288
+ status: "unavailable";
289
+ };
290
+ isMerchListing: boolean | null;
291
+ isUnavailable: boolean;
292
+ };
293
+ category: {
294
+ id: number;
295
+ name: string | null;
296
+ } | null;
297
+ salesRank: {
298
+ current: number | null;
299
+ averages: {
300
+ last30Days: number | null;
301
+ last90Days: number | null;
302
+ };
303
+ };
304
+ price: {
305
+ amountMinor: number;
306
+ currencyCode: string;
307
+ } | null;
308
+ demand: {
309
+ boughtInPastMonth: number | null;
310
+ salesRankDrops: {
311
+ last30Days: number | null;
312
+ last90Days: number | null;
313
+ last180Days: number | null;
314
+ last365Days: number | null;
315
+ };
316
+ };
317
+ }
318
+ export interface ProductSearchProduct {
319
+ marketplaceId: string;
320
+ asin: string;
321
+ title: string | null;
322
+ brand: string | null;
323
+ thumbnail: {
324
+ status: "available";
325
+ url: string;
326
+ } | {
327
+ status: "unavailable";
43
328
  };
44
- price?: {
45
- unit: "minorCurrency";
46
- currencyCode: "USD";
47
- valueScale: 100;
48
- buckets: HistoryBucketTuple[];
49
- summary: HistoryBucketSummary;
329
+ isMerchListing: boolean | null;
330
+ isUnavailable: boolean;
331
+ category: {
332
+ id: number;
333
+ name: string | null;
334
+ } | null;
335
+ salesRank: number | null;
336
+ price: {
337
+ amountMinor: number;
338
+ currencyCode: string;
339
+ } | null;
340
+ boughtInPastMonth: number | null;
341
+ }
342
+ export interface ProductSearch {
343
+ keyword: string;
344
+ searchedAt: string;
345
+ results: Array<{
346
+ organicSearchPlacement: number;
347
+ product: ProductSearchProduct;
348
+ }>;
349
+ }
350
+ export type BasicProduct = {
351
+ marketplaceId: string;
352
+ asin: string;
353
+ status: "available";
354
+ title: string | null;
355
+ thumbnail: {
356
+ status: "available";
357
+ url: string;
358
+ } | {
359
+ status: "unavailable";
50
360
  };
361
+ } | {
362
+ marketplaceId: string;
363
+ asin: string;
364
+ status: "unavailable";
51
365
  };
52
- export type AgentHistoryResponse = {
53
- schemaVersion: 2;
366
+ export interface ProductHistorySummary {
367
+ first: number | null;
368
+ latest: number | null;
369
+ min: number | null;
370
+ max: number | null;
371
+ }
372
+ export interface PublicProductHistory {
54
373
  marketplaceId: string;
55
374
  asin: string;
56
- status: "collecting" | "ready" | "empty";
57
- latestImportAt: string | null;
58
- syncTriggered: boolean;
59
375
  range: {
60
376
  startAt: string;
61
377
  endAt: string;
62
- bucket: ResolvedHistoryBucket;
378
+ interval: "day" | "week" | "month";
63
379
  };
64
- series: AgentHistorySeries;
65
- };
66
- export type ProductInfo = {
67
- asin: string;
68
- marketplaceId: string;
69
- dateFirstAvailable: string | null;
70
- title: string | null;
71
- brand: string | null;
72
- isMerchListing: boolean;
73
- bullet1: string | null;
74
- bullet2: string | null;
75
- rootCategoryId: number | null;
76
- rootCategoryBsr: number | null;
77
- rootCategoryDisplayName: string | null;
78
- thumbnailUrl?: string;
79
- metadata: {
80
- lastFetched: string;
81
- cached: boolean;
380
+ series: {
381
+ salesRank?: {
382
+ unit: "rank";
383
+ category: {
384
+ id: number;
385
+ name: string | null;
386
+ } | null;
387
+ points: [
388
+ periodStart: string,
389
+ valueAtPeriodEnd: number | null
390
+ ][];
391
+ summary: ProductHistorySummary;
392
+ };
393
+ price?: {
394
+ unit: "minorCurrency";
395
+ currencyCode: string;
396
+ points: [
397
+ periodStart: string,
398
+ valueAtPeriodEnd: number | null
399
+ ][];
400
+ summary: ProductHistorySummary;
401
+ };
82
402
  };
83
- };
403
+ }
84
404
  export declare const publicAppRouter: import("@trpc/server").TRPCBuiltRouter<{
85
405
  ctx: {
86
- user: ClerkUser;
87
- isAdmin: boolean;
88
- authType: "license" | "clerk" | "none";
89
- license: {
90
- key: string;
91
- data: LicenseUsageData | undefined;
92
- };
93
- licenseError: undefined;
94
- request: import("fastify").FastifyRequest<import("fastify").RouteGenericInterface, import("fastify").RawServerDefault, import("http").IncomingMessage, import("fastify").FastifySchema, import("fastify").FastifyTypeProviderDefault, unknown, import("fastify").FastifyBaseLogger, import("fastify/types/type-provider.js").ResolveFastifyRequestType<import("fastify").FastifyTypeProviderDefault, import("fastify").FastifySchema, import("fastify").RouteGenericInterface>>;
95
- } | {
96
406
  user: null;
97
407
  isAdmin: boolean;
98
- authType: "license" | "clerk" | "none";
99
- license: null;
100
- licenseError: string | undefined;
101
- request: import("fastify").FastifyRequest<import("fastify").RouteGenericInterface, import("fastify").RawServerDefault, import("http").IncomingMessage, import("fastify").FastifySchema, import("fastify").FastifyTypeProviderDefault, unknown, import("fastify").FastifyBaseLogger, import("fastify/types/type-provider.js").ResolveFastifyRequestType<import("fastify").FastifyTypeProviderDefault, import("fastify").FastifySchema, import("fastify").RouteGenericInterface>>;
408
+ authType: "none";
409
+ credentialKind: null;
410
+ authExpiresAtMs: null;
411
+ accessPrincipal: null;
412
+ accessError: import("@merchbaseco/access").ServiceAccessErrorCode | null;
413
+ request: ContextRequest;
102
414
  } | {
103
415
  user: ClerkUser;
104
416
  isAdmin: boolean;
105
- authType: "license" | "clerk" | "none";
106
- license: null;
107
- licenseError: undefined;
108
- request: import("fastify").FastifyRequest<import("fastify").RouteGenericInterface, import("fastify").RawServerDefault, import("http").IncomingMessage, import("fastify").FastifySchema, import("fastify").FastifyTypeProviderDefault, unknown, import("fastify").FastifyBaseLogger, import("fastify/types/type-provider.js").ResolveFastifyRequestType<import("fastify").FastifyTypeProviderDefault, import("fastify").FastifySchema, import("fastify").RouteGenericInterface>>;
417
+ authType: "access";
418
+ credentialKind: CredentialKind;
419
+ authExpiresAtMs: number | null;
420
+ accessPrincipal: RankWranglerServicePrincipal;
421
+ accessError: null;
422
+ request: ContextRequest;
109
423
  };
110
424
  meta: object;
111
425
  errorShape: import("@trpc/server").TRPCDefaultErrorShape;
@@ -113,29 +427,23 @@ export declare const publicAppRouter: import("@trpc/server").TRPCBuiltRouter<{
113
427
  }, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
114
428
  api: import("@trpc/server").TRPCBuiltRouter<{
115
429
  ctx: {
116
- user: ClerkUser;
117
- isAdmin: boolean;
118
- authType: "license" | "clerk" | "none";
119
- license: {
120
- key: string;
121
- data: LicenseUsageData | undefined;
122
- };
123
- licenseError: undefined;
124
- request: import("fastify").FastifyRequest<import("fastify").RouteGenericInterface, import("fastify").RawServerDefault, import("http").IncomingMessage, import("fastify").FastifySchema, import("fastify").FastifyTypeProviderDefault, unknown, import("fastify").FastifyBaseLogger, import("fastify/types/type-provider.js").ResolveFastifyRequestType<import("fastify").FastifyTypeProviderDefault, import("fastify").FastifySchema, import("fastify").RouteGenericInterface>>;
125
- } | {
126
430
  user: null;
127
431
  isAdmin: boolean;
128
- authType: "license" | "clerk" | "none";
129
- license: null;
130
- licenseError: string | undefined;
131
- request: import("fastify").FastifyRequest<import("fastify").RouteGenericInterface, import("fastify").RawServerDefault, import("http").IncomingMessage, import("fastify").FastifySchema, import("fastify").FastifyTypeProviderDefault, unknown, import("fastify").FastifyBaseLogger, import("fastify/types/type-provider.js").ResolveFastifyRequestType<import("fastify").FastifyTypeProviderDefault, import("fastify").FastifySchema, import("fastify").RouteGenericInterface>>;
432
+ authType: "none";
433
+ credentialKind: null;
434
+ authExpiresAtMs: null;
435
+ accessPrincipal: null;
436
+ accessError: import("@merchbaseco/access").ServiceAccessErrorCode | null;
437
+ request: ContextRequest;
132
438
  } | {
133
439
  user: ClerkUser;
134
440
  isAdmin: boolean;
135
- authType: "license" | "clerk" | "none";
136
- license: null;
137
- licenseError: undefined;
138
- request: import("fastify").FastifyRequest<import("fastify").RouteGenericInterface, import("fastify").RawServerDefault, import("http").IncomingMessage, import("fastify").FastifySchema, import("fastify").FastifyTypeProviderDefault, unknown, import("fastify").FastifyBaseLogger, import("fastify/types/type-provider.js").ResolveFastifyRequestType<import("fastify").FastifyTypeProviderDefault, import("fastify").FastifySchema, import("fastify").RouteGenericInterface>>;
441
+ authType: "access";
442
+ credentialKind: CredentialKind;
443
+ authExpiresAtMs: number | null;
444
+ accessPrincipal: RankWranglerServicePrincipal;
445
+ accessError: null;
446
+ request: ContextRequest;
139
447
  };
140
448
  meta: object;
141
449
  errorShape: import("@trpc/server").TRPCDefaultErrorShape;
@@ -143,200 +451,156 @@ export declare const publicAppRouter: import("@trpc/server").TRPCBuiltRouter<{
143
451
  }, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
144
452
  public: import("@trpc/server").TRPCBuiltRouter<{
145
453
  ctx: {
146
- user: ClerkUser;
147
- isAdmin: boolean;
148
- authType: "license" | "clerk" | "none";
149
- license: {
150
- key: string;
151
- data: LicenseUsageData | undefined;
152
- };
153
- licenseError: undefined;
154
- request: import("fastify").FastifyRequest<import("fastify").RouteGenericInterface, import("fastify").RawServerDefault, import("http").IncomingMessage, import("fastify").FastifySchema, import("fastify").FastifyTypeProviderDefault, unknown, import("fastify").FastifyBaseLogger, import("fastify/types/type-provider.js").ResolveFastifyRequestType<import("fastify").FastifyTypeProviderDefault, import("fastify").FastifySchema, import("fastify").RouteGenericInterface>>;
155
- } | {
156
454
  user: null;
157
455
  isAdmin: boolean;
158
- authType: "license" | "clerk" | "none";
159
- license: null;
160
- licenseError: string | undefined;
161
- request: import("fastify").FastifyRequest<import("fastify").RouteGenericInterface, import("fastify").RawServerDefault, import("http").IncomingMessage, import("fastify").FastifySchema, import("fastify").FastifyTypeProviderDefault, unknown, import("fastify").FastifyBaseLogger, import("fastify/types/type-provider.js").ResolveFastifyRequestType<import("fastify").FastifyTypeProviderDefault, import("fastify").FastifySchema, import("fastify").RouteGenericInterface>>;
456
+ authType: "none";
457
+ credentialKind: null;
458
+ authExpiresAtMs: null;
459
+ accessPrincipal: null;
460
+ accessError: import("@merchbaseco/access").ServiceAccessErrorCode | null;
461
+ request: ContextRequest;
162
462
  } | {
163
463
  user: ClerkUser;
164
464
  isAdmin: boolean;
165
- authType: "license" | "clerk" | "none";
166
- license: null;
167
- licenseError: undefined;
168
- request: import("fastify").FastifyRequest<import("fastify").RouteGenericInterface, import("fastify").RawServerDefault, import("http").IncomingMessage, import("fastify").FastifySchema, import("fastify").FastifyTypeProviderDefault, unknown, import("fastify").FastifyBaseLogger, import("fastify/types/type-provider.js").ResolveFastifyRequestType<import("fastify").FastifyTypeProviderDefault, import("fastify").FastifySchema, import("fastify").RouteGenericInterface>>;
465
+ authType: "access";
466
+ credentialKind: CredentialKind;
467
+ authExpiresAtMs: number | null;
468
+ accessPrincipal: RankWranglerServicePrincipal;
469
+ accessError: null;
470
+ request: ContextRequest;
169
471
  };
170
472
  meta: object;
171
473
  errorShape: import("@trpc/server").TRPCDefaultErrorShape;
172
474
  transformer: false;
173
475
  }, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
174
- getProductHistory: import("@trpc/server").TRPCMutationProcedure<{
175
- input: {
176
- marketplaceId: string;
177
- asin: string;
178
- startAt?: unknown;
179
- endAt?: unknown;
180
- limit?: unknown;
181
- days?: unknown;
182
- metrics?: ("bsr" | "price")[] | undefined;
183
- format?: "legacy" | "agent" | undefined;
184
- bucket?: "auto" | "day" | "week" | "month" | undefined;
185
- };
186
- output: AgentHistoryResponse | {
187
- syncTriggered: boolean;
188
- marketplaceId: string;
189
- asin: string;
190
- metric: "bsrMain" | "bsrCategory" | "priceAmazon" | "priceNew" | "priceNewFba";
191
- latestImportAt: string | null;
192
- categoryNames: {
193
- [x: string]: string;
194
- };
195
- points: {
196
- categoryId: number;
197
- categoryName: string;
198
- observedAt: string;
199
- keepaMinutes: number;
200
- value: number | null;
201
- isMissing: boolean;
202
- }[];
203
- } | {
204
- marketplaceId: string;
205
- asin: string;
206
- metric: "bsrMain";
207
- latestImportAt: string | null;
208
- categoryNames: Record<string, string>;
209
- points: {
210
- categoryId: number;
211
- categoryName: string | null;
212
- observedAt: string;
213
- keepaMinutes: number;
214
- value: number | null;
215
- isMissing: boolean;
216
- }[];
217
- collecting: boolean;
218
- syncTriggered: boolean;
219
- };
220
- meta: object;
221
- }>;
222
- getProductInfoBatch: import("@trpc/server").TRPCMutationProcedure<{
223
- input: {
224
- marketplaceId: string;
225
- asins: string[];
226
- };
227
- output: {
228
- marketplaceId: string;
229
- items: ({
230
- asin: string;
231
- success: true;
232
- data: ProductInfo;
233
- } | {
234
- asin: string;
235
- success: false;
236
- error: string;
237
- code: "UNAUTHORIZED" | "PARSE_ERROR" | "BAD_REQUEST" | "INTERNAL_SERVER_ERROR" | "NOT_IMPLEMENTED" | "BAD_GATEWAY" | "SERVICE_UNAVAILABLE" | "GATEWAY_TIMEOUT" | "PAYMENT_REQUIRED" | "FORBIDDEN" | "NOT_FOUND" | "METHOD_NOT_SUPPORTED" | "TIMEOUT" | "CONFLICT" | "PRECONDITION_FAILED" | "PAYLOAD_TOO_LARGE" | "UNSUPPORTED_MEDIA_TYPE" | "UNPROCESSABLE_CONTENT" | "PRECONDITION_REQUIRED" | "TOO_MANY_REQUESTS" | "CLIENT_CLOSED_REQUEST";
238
- })[];
239
- meta: {
240
- requestedCount: number;
241
- successCount: number;
242
- errorCount: number;
243
- };
244
- };
245
- meta: object;
246
- }>;
247
- getProductInfo: import("@trpc/server").TRPCMutationProcedure<{
248
- input: {
249
- marketplaceId: string;
250
- asin: string;
251
- };
252
- output: ProductInfo;
253
- meta: object;
254
- }>;
255
- dev: import("@trpc/server").TRPCBuiltRouter<{
476
+ keyword: import("@trpc/server").TRPCBuiltRouter<{
256
477
  ctx: {
257
- user: ClerkUser;
258
- isAdmin: boolean;
259
- authType: "license" | "clerk" | "none";
260
- license: {
261
- key: string;
262
- data: LicenseUsageData | undefined;
263
- };
264
- licenseError: undefined;
265
- request: import("fastify").FastifyRequest<import("fastify").RouteGenericInterface, import("fastify").RawServerDefault, import("http").IncomingMessage, import("fastify").FastifySchema, import("fastify").FastifyTypeProviderDefault, unknown, import("fastify").FastifyBaseLogger, import("fastify/types/type-provider.js").ResolveFastifyRequestType<import("fastify").FastifyTypeProviderDefault, import("fastify").FastifySchema, import("fastify").RouteGenericInterface>>;
266
- } | {
267
478
  user: null;
268
479
  isAdmin: boolean;
269
- authType: "license" | "clerk" | "none";
270
- license: null;
271
- licenseError: string | undefined;
272
- request: import("fastify").FastifyRequest<import("fastify").RouteGenericInterface, import("fastify").RawServerDefault, import("http").IncomingMessage, import("fastify").FastifySchema, import("fastify").FastifyTypeProviderDefault, unknown, import("fastify").FastifyBaseLogger, import("fastify/types/type-provider.js").ResolveFastifyRequestType<import("fastify").FastifyTypeProviderDefault, import("fastify").FastifySchema, import("fastify").RouteGenericInterface>>;
480
+ authType: "none";
481
+ credentialKind: null;
482
+ authExpiresAtMs: null;
483
+ accessPrincipal: null;
484
+ accessError: import("@merchbaseco/access").ServiceAccessErrorCode | null;
485
+ request: ContextRequest;
273
486
  } | {
274
487
  user: ClerkUser;
275
488
  isAdmin: boolean;
276
- authType: "license" | "clerk" | "none";
277
- license: null;
278
- licenseError: undefined;
279
- request: import("fastify").FastifyRequest<import("fastify").RouteGenericInterface, import("fastify").RawServerDefault, import("http").IncomingMessage, import("fastify").FastifySchema, import("fastify").FastifyTypeProviderDefault, unknown, import("fastify").FastifyBaseLogger, import("fastify/types/type-provider.js").ResolveFastifyRequestType<import("fastify").FastifyTypeProviderDefault, import("fastify").FastifySchema, import("fastify").RouteGenericInterface>>;
489
+ authType: "access";
490
+ credentialKind: CredentialKind;
491
+ authExpiresAtMs: number | null;
492
+ accessPrincipal: RankWranglerServicePrincipal;
493
+ accessError: null;
494
+ request: ContextRequest;
280
495
  };
281
496
  meta: object;
282
497
  errorShape: import("@trpc/server").TRPCDefaultErrorShape;
283
498
  transformer: false;
284
499
  }, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
285
- createClerkSignInToken: import("@trpc/server").TRPCMutationProcedure<{
286
- input: void;
500
+ get: import("@trpc/server").TRPCQueryProcedure<{
501
+ input: {
502
+ keyword: string;
503
+ dataEndDate?: string | undefined;
504
+ dataStartDate?: string | undefined;
505
+ marketplaceId?: "ATVPDKIKX0DER" | undefined;
506
+ reportPeriod?: "DAY" | "WEEK" | undefined;
507
+ };
287
508
  output: {
288
- ticket: string;
289
- expiresInSeconds: number;
509
+ keyword: string;
510
+ status: "ready" | "empty";
511
+ current: KeywordCurrent | null;
290
512
  };
291
513
  meta: object;
292
514
  }>;
515
+ history: import("@trpc/server").TRPCQueryProcedure<{
516
+ input: {
517
+ keyword: string;
518
+ marketplaceId?: "ATVPDKIKX0DER" | undefined;
519
+ rangeDays?: number | undefined;
520
+ reportPeriod?: "DAY" | "WEEK" | undefined;
521
+ };
522
+ output: KeywordHistoryResponse;
523
+ meta: object;
524
+ }>;
525
+ search: import("@trpc/server").TRPCQueryProcedure<{
526
+ input: {
527
+ text: string;
528
+ cursor?: number | undefined;
529
+ limit?: number | undefined;
530
+ maxRank?: number | undefined;
531
+ merchOnly?: boolean | undefined;
532
+ minRank?: number | undefined;
533
+ dataEndDate?: string | undefined;
534
+ dataStartDate?: string | undefined;
535
+ marketplaceId?: "ATVPDKIKX0DER" | undefined;
536
+ reportPeriod?: "DAY" | "WEEK" | undefined;
537
+ };
538
+ output: KeywordSearchResponse;
539
+ meta: object;
540
+ }>;
293
541
  }>>;
294
- license: import("@trpc/server").TRPCBuiltRouter<{
542
+ product: import("@trpc/server").TRPCBuiltRouter<{
295
543
  ctx: {
296
- user: ClerkUser;
297
- isAdmin: boolean;
298
- authType: "license" | "clerk" | "none";
299
- license: {
300
- key: string;
301
- data: LicenseUsageData | undefined;
302
- };
303
- licenseError: undefined;
304
- request: import("fastify").FastifyRequest<import("fastify").RouteGenericInterface, import("fastify").RawServerDefault, import("http").IncomingMessage, import("fastify").FastifySchema, import("fastify").FastifyTypeProviderDefault, unknown, import("fastify").FastifyBaseLogger, import("fastify/types/type-provider.js").ResolveFastifyRequestType<import("fastify").FastifyTypeProviderDefault, import("fastify").FastifySchema, import("fastify").RouteGenericInterface>>;
305
- } | {
306
544
  user: null;
307
545
  isAdmin: boolean;
308
- authType: "license" | "clerk" | "none";
309
- license: null;
310
- licenseError: string | undefined;
311
- request: import("fastify").FastifyRequest<import("fastify").RouteGenericInterface, import("fastify").RawServerDefault, import("http").IncomingMessage, import("fastify").FastifySchema, import("fastify").FastifyTypeProviderDefault, unknown, import("fastify").FastifyBaseLogger, import("fastify/types/type-provider.js").ResolveFastifyRequestType<import("fastify").FastifyTypeProviderDefault, import("fastify").FastifySchema, import("fastify").RouteGenericInterface>>;
546
+ authType: "none";
547
+ credentialKind: null;
548
+ authExpiresAtMs: null;
549
+ accessPrincipal: null;
550
+ accessError: import("@merchbaseco/access").ServiceAccessErrorCode | null;
551
+ request: ContextRequest;
312
552
  } | {
313
553
  user: ClerkUser;
314
554
  isAdmin: boolean;
315
- authType: "license" | "clerk" | "none";
316
- license: null;
317
- licenseError: undefined;
318
- request: import("fastify").FastifyRequest<import("fastify").RouteGenericInterface, import("fastify").RawServerDefault, import("http").IncomingMessage, import("fastify").FastifySchema, import("fastify").FastifyTypeProviderDefault, unknown, import("fastify").FastifyBaseLogger, import("fastify/types/type-provider.js").ResolveFastifyRequestType<import("fastify").FastifyTypeProviderDefault, import("fastify").FastifySchema, import("fastify").RouteGenericInterface>>;
555
+ authType: "access";
556
+ credentialKind: CredentialKind;
557
+ authExpiresAtMs: number | null;
558
+ accessPrincipal: RankWranglerServicePrincipal;
559
+ accessError: null;
560
+ request: ContextRequest;
319
561
  };
320
562
  meta: object;
321
563
  errorShape: import("@trpc/server").TRPCDefaultErrorShape;
322
564
  transformer: false;
323
565
  }, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
324
- validate: import("@trpc/server").TRPCMutationProcedure<{
325
- input: void;
326
- output: {
327
- email: string;
328
- usage: number;
329
- usageLimit: number;
566
+ get: import("@trpc/server").TRPCMutationProcedure<{
567
+ input: {
568
+ marketplaceId: string;
569
+ asin: string;
330
570
  };
571
+ output: Product;
331
572
  meta: object;
332
573
  }>;
333
- status: import("@trpc/server").TRPCMutationProcedure<{
334
- input: void;
335
- output: {
336
- email: string;
337
- usage: number;
338
- usageLimit: number;
574
+ getMany: import("@trpc/server").TRPCMutationProcedure<{
575
+ input: {
576
+ products: {
577
+ marketplaceId: string;
578
+ asin: string;
579
+ }[];
580
+ };
581
+ output: BasicProduct[];
582
+ meta: object;
583
+ }>;
584
+ history: import("@trpc/server").TRPCMutationProcedure<{
585
+ input: {
586
+ marketplaceId: string;
587
+ asin: string;
588
+ bucket?: "auto" | "day" | "week" | "month" | undefined;
589
+ days?: unknown;
590
+ endAt?: unknown;
591
+ limit?: unknown;
592
+ metrics?: ("price" | "salesRank")[] | undefined;
593
+ startAt?: unknown;
594
+ };
595
+ output: PublicProductHistory;
596
+ meta: object;
597
+ }>;
598
+ search: import("@trpc/server").TRPCMutationProcedure<{
599
+ input: {
600
+ term: string;
601
+ refresh?: boolean | undefined;
339
602
  };
603
+ output: ProductSearch;
340
604
  meta: object;
341
605
  }>;
342
606
  }>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rankwrangler/http-client",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "description": "Typed tRPC client for RankWrangler",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -15,6 +15,9 @@
15
15
  "dist",
16
16
  "README.md"
17
17
  ],
18
+ "scripts": {
19
+ "test": "tsc -p tsconfig.test.json && bun test test/*.test.ts"
20
+ },
18
21
  "publishConfig": {
19
22
  "access": "public",
20
23
  "provenance": true