@rankwrangler/http-client 0.5.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
- set -a
58
- source ../../.env
59
- set +a
60
- npm whoami --userconfig ../../.npmrc
61
- npm publish --access public --userconfig ../../.npmrc
62
- ```
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,58 +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
- export type ProductInfo = {
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"
203
+ ];
204
+ declare const TOP_SEARCH_TERMS_REFRESH_TRIGGERS: readonly [
205
+ "requested",
206
+ "automatic"
207
+ ];
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;
214
+ };
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;
14
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 {
15
319
  marketplaceId: string;
16
- dateFirstAvailable: string | null;
320
+ asin: string;
17
321
  title: string | null;
18
322
  brand: string | null;
19
- isMerchListing: boolean;
20
- bullet1: string | null;
21
- bullet2: string | null;
22
- rootCategoryId: number | null;
23
- rootCategoryBsr: number | null;
24
- rootCategoryDisplayName: string | null;
25
- thumbnailUrl?: string;
26
- metadata: {
27
- lastFetched: string;
28
- cached: boolean;
323
+ thumbnail: {
324
+ status: "available";
325
+ url: string;
326
+ } | {
327
+ status: "unavailable";
328
+ };
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";
29
360
  };
361
+ } | {
362
+ marketplaceId: string;
363
+ asin: string;
364
+ status: "unavailable";
30
365
  };
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 {
373
+ marketplaceId: string;
374
+ asin: string;
375
+ range: {
376
+ startAt: string;
377
+ endAt: string;
378
+ interval: "day" | "week" | "month";
379
+ };
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
+ };
402
+ };
403
+ }
31
404
  export declare const publicAppRouter: import("@trpc/server").TRPCBuiltRouter<{
32
405
  ctx: {
33
- user: ClerkUser;
34
- isAdmin: boolean;
35
- authType: "license" | "clerk" | "none";
36
- license: {
37
- key: string;
38
- data: LicenseUsageData | undefined;
39
- };
40
- licenseError: undefined;
41
- 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>>;
42
- } | {
43
406
  user: null;
44
407
  isAdmin: boolean;
45
- authType: "license" | "clerk" | "none";
46
- license: null;
47
- licenseError: string | undefined;
48
- 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;
49
414
  } | {
50
415
  user: ClerkUser;
51
416
  isAdmin: boolean;
52
- authType: "license" | "clerk" | "none";
53
- license: null;
54
- licenseError: undefined;
55
- 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;
56
423
  };
57
424
  meta: object;
58
425
  errorShape: import("@trpc/server").TRPCDefaultErrorShape;
@@ -60,29 +427,23 @@ export declare const publicAppRouter: import("@trpc/server").TRPCBuiltRouter<{
60
427
  }, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
61
428
  api: import("@trpc/server").TRPCBuiltRouter<{
62
429
  ctx: {
63
- user: ClerkUser;
64
- isAdmin: boolean;
65
- authType: "license" | "clerk" | "none";
66
- license: {
67
- key: string;
68
- data: LicenseUsageData | undefined;
69
- };
70
- licenseError: undefined;
71
- 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>>;
72
- } | {
73
430
  user: null;
74
431
  isAdmin: boolean;
75
- authType: "license" | "clerk" | "none";
76
- license: null;
77
- licenseError: string | undefined;
78
- 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;
79
438
  } | {
80
439
  user: ClerkUser;
81
440
  isAdmin: boolean;
82
- authType: "license" | "clerk" | "none";
83
- license: null;
84
- licenseError: undefined;
85
- 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;
86
447
  };
87
448
  meta: object;
88
449
  errorShape: import("@trpc/server").TRPCDefaultErrorShape;
@@ -90,230 +451,156 @@ export declare const publicAppRouter: import("@trpc/server").TRPCBuiltRouter<{
90
451
  }, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
91
452
  public: import("@trpc/server").TRPCBuiltRouter<{
92
453
  ctx: {
93
- user: ClerkUser;
94
- isAdmin: boolean;
95
- authType: "license" | "clerk" | "none";
96
- license: {
97
- key: string;
98
- data: LicenseUsageData | undefined;
99
- };
100
- licenseError: 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>>;
102
- } | {
103
454
  user: null;
104
455
  isAdmin: boolean;
105
- authType: "license" | "clerk" | "none";
106
- license: null;
107
- licenseError: string | 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>>;
456
+ authType: "none";
457
+ credentialKind: null;
458
+ authExpiresAtMs: null;
459
+ accessPrincipal: null;
460
+ accessError: import("@merchbaseco/access").ServiceAccessErrorCode | null;
461
+ request: ContextRequest;
109
462
  } | {
110
463
  user: ClerkUser;
111
464
  isAdmin: boolean;
112
- authType: "license" | "clerk" | "none";
113
- license: null;
114
- licenseError: undefined;
115
- 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;
116
471
  };
117
472
  meta: object;
118
473
  errorShape: import("@trpc/server").TRPCDefaultErrorShape;
119
474
  transformer: false;
120
475
  }, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
121
- getProductHistory: import("@trpc/server").TRPCMutationProcedure<{
122
- input: {
123
- marketplaceId: string;
124
- asin: string;
125
- startAt?: unknown;
126
- endAt?: unknown;
127
- limit?: unknown;
128
- days?: unknown;
129
- metrics?: ("bsr" | "price")[] | undefined;
130
- format?: "legacy" | "agent" | undefined;
131
- };
132
- output: {
133
- marketplaceId: string;
134
- asin: string;
135
- metric: "bsrMain";
136
- latestImportAt: string | null;
137
- categoryNames: Record<string, string>;
138
- points: {
139
- categoryId: number;
140
- categoryName: string | null;
141
- observedAt: string;
142
- keepaMinutes: number;
143
- value: number | null;
144
- isMissing: boolean;
145
- }[];
146
- collecting: boolean;
147
- syncTriggered: boolean;
148
- } | {
149
- schemaVersion: 1;
150
- status: string;
151
- latestImportAt: string | null;
152
- series: {
153
- price?: {
154
- unit: "minorCurrency";
155
- currencyCode: "USD";
156
- valueScale: 100;
157
- points: ([
158
- string,
159
- number | null
160
- ] | [
161
- string,
162
- null,
163
- 1
164
- ])[];
165
- } | undefined;
166
- bsr?: {
167
- unit: "rank";
168
- category: {
169
- id: number;
170
- name: string;
171
- } | null;
172
- points: ([
173
- string,
174
- number | null
175
- ] | [
176
- string,
177
- null,
178
- 1
179
- ])[];
180
- } | undefined;
181
- };
182
- marketplaceId: string;
183
- asin: string;
184
- metric: "bsrMain";
185
- categoryNames: Record<string, string>;
186
- points: {
187
- categoryId: number;
188
- categoryName: string | null;
189
- observedAt: string;
190
- keepaMinutes: number;
191
- value: number | null;
192
- isMissing: boolean;
193
- }[];
194
- collecting: boolean;
195
- syncTriggered: boolean;
196
- };
197
- meta: object;
198
- }>;
199
- getProductInfoBatch: import("@trpc/server").TRPCMutationProcedure<{
200
- input: {
201
- marketplaceId: string;
202
- asins: string[];
203
- };
204
- output: {
205
- marketplaceId: string;
206
- items: ({
207
- asin: string;
208
- success: true;
209
- data: ProductInfo;
210
- } | {
211
- asin: string;
212
- success: false;
213
- error: string;
214
- 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";
215
- })[];
216
- meta: {
217
- requestedCount: number;
218
- successCount: number;
219
- errorCount: number;
220
- };
221
- };
222
- meta: object;
223
- }>;
224
- getProductInfo: import("@trpc/server").TRPCMutationProcedure<{
225
- input: {
226
- marketplaceId: string;
227
- asin: string;
228
- };
229
- output: ProductInfo;
230
- meta: object;
231
- }>;
232
- dev: import("@trpc/server").TRPCBuiltRouter<{
476
+ keyword: import("@trpc/server").TRPCBuiltRouter<{
233
477
  ctx: {
234
- user: ClerkUser;
235
- isAdmin: boolean;
236
- authType: "license" | "clerk" | "none";
237
- license: {
238
- key: string;
239
- data: LicenseUsageData | undefined;
240
- };
241
- licenseError: undefined;
242
- 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>>;
243
- } | {
244
478
  user: null;
245
479
  isAdmin: boolean;
246
- authType: "license" | "clerk" | "none";
247
- license: null;
248
- licenseError: string | undefined;
249
- 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;
250
486
  } | {
251
487
  user: ClerkUser;
252
488
  isAdmin: boolean;
253
- authType: "license" | "clerk" | "none";
254
- license: null;
255
- licenseError: undefined;
256
- 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;
257
495
  };
258
496
  meta: object;
259
497
  errorShape: import("@trpc/server").TRPCDefaultErrorShape;
260
498
  transformer: false;
261
499
  }, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
262
- createClerkSignInToken: import("@trpc/server").TRPCMutationProcedure<{
263
- 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
+ };
264
508
  output: {
265
- ticket: string;
266
- expiresInSeconds: number;
509
+ keyword: string;
510
+ status: "ready" | "empty";
511
+ current: KeywordCurrent | null;
512
+ };
513
+ meta: object;
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;
267
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;
268
539
  meta: object;
269
540
  }>;
270
541
  }>>;
271
- license: import("@trpc/server").TRPCBuiltRouter<{
542
+ product: import("@trpc/server").TRPCBuiltRouter<{
272
543
  ctx: {
273
- user: ClerkUser;
274
- isAdmin: boolean;
275
- authType: "license" | "clerk" | "none";
276
- license: {
277
- key: string;
278
- data: LicenseUsageData | undefined;
279
- };
280
- licenseError: undefined;
281
- 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>>;
282
- } | {
283
544
  user: null;
284
545
  isAdmin: boolean;
285
- authType: "license" | "clerk" | "none";
286
- license: null;
287
- licenseError: string | undefined;
288
- 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;
289
552
  } | {
290
553
  user: ClerkUser;
291
554
  isAdmin: boolean;
292
- authType: "license" | "clerk" | "none";
293
- license: null;
294
- licenseError: undefined;
295
- 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;
296
561
  };
297
562
  meta: object;
298
563
  errorShape: import("@trpc/server").TRPCDefaultErrorShape;
299
564
  transformer: false;
300
565
  }, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
301
- validate: import("@trpc/server").TRPCMutationProcedure<{
302
- input: void;
303
- output: {
304
- email: string;
305
- usage: number;
306
- usageLimit: number;
566
+ get: import("@trpc/server").TRPCMutationProcedure<{
567
+ input: {
568
+ marketplaceId: string;
569
+ asin: string;
307
570
  };
571
+ output: Product;
308
572
  meta: object;
309
573
  }>;
310
- status: import("@trpc/server").TRPCMutationProcedure<{
311
- input: void;
312
- output: {
313
- email: string;
314
- usage: number;
315
- 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;
316
602
  };
603
+ output: ProductSearch;
317
604
  meta: object;
318
605
  }>;
319
606
  }>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rankwrangler/http-client",
3
- "version": "0.5.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,13 +15,17 @@
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
- "access": "public"
22
+ "access": "public",
23
+ "provenance": true
20
24
  },
21
25
  "sideEffects": false,
22
26
  "dependencies": {
23
- "@trpc/client": "^11.0.0",
24
- "@trpc/server": "^11.0.0"
27
+ "@trpc/client": "11.10.0",
28
+ "@trpc/server": "11.10.0"
25
29
  },
26
30
  "packageManager": "bun@1.1.27"
27
31
  }