hibi-client 0.3.0 → 0.5.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
@@ -8,6 +8,17 @@ Official TypeScript client for the [Hibi](https://github.com/YannickHerrero/hibi
8
8
  pnpm add hibi-client
9
9
  ```
10
10
 
11
+ ## Getting an API key
12
+
13
+ Hibi uses per-user API keys. Keys are issued from the user's portal at [app.hibi.app](https://app.hibi.app) under **API keys**:
14
+
15
+ 1. Sign in to the portal (email OTP).
16
+ 2. Create a key with a recognizable name (e.g. "My third-party app").
17
+ 3. Copy the raw key — it is shown **once** at creation and stored hashed afterward.
18
+ 4. Paste the key into your app or have your end users paste theirs.
19
+
20
+ Each user authenticates with their own key. Third-party apps should prompt the user for their key rather than embedding one. Keys can be revoked at any time from the portal.
21
+
11
22
  ## Usage
12
23
 
13
24
  ```ts
package/dist/index.cjs CHANGED
@@ -41,6 +41,30 @@ zod.z.object({
41
41
  apiKey: ApiKeySchema,
42
42
  rawKey: zod.z.string()
43
43
  });
44
+ zod.z.object({
45
+ apiKey: zod.z.string().min(1).max(512)
46
+ });
47
+ zod.z.object({
48
+ label: zod.z.string(),
49
+ usage: zod.z.number().nullable(),
50
+ limit: zod.z.number().nullable()
51
+ });
52
+ zod.z.object({
53
+ configured: zod.z.boolean(),
54
+ keyLabel: zod.z.string().nullable().optional(),
55
+ updatedAt: TimestampSchema.nullable().optional()
56
+ });
57
+ var ClientAiStatusSchema = zod.z.discriminatedUnion("configured", [
58
+ zod.z.object({
59
+ configured: zod.z.literal(true),
60
+ label: zod.z.string(),
61
+ usage: zod.z.number().nullable(),
62
+ limit: zod.z.number().nullable()
63
+ }),
64
+ zod.z.object({
65
+ configured: zod.z.literal(false)
66
+ })
67
+ ]);
44
68
  var FuriganaPairSchema = zod.z.object({
45
69
  base: zod.z.string(),
46
70
  reading: zod.z.string()
@@ -65,6 +89,8 @@ var CardSchema = zod.z.object({
65
89
  kanjiList: zod.z.array(KanjiEntrySchema),
66
90
  imageKey: zod.z.string().nullable(),
67
91
  audioKey: zod.z.string().nullable(),
92
+ imageUrl: zod.z.string().url().nullable(),
93
+ audioUrl: zod.z.string().url().nullable(),
68
94
  source: zod.z.string(),
69
95
  tags: zod.z.array(zod.z.string())
70
96
  });
@@ -72,14 +98,19 @@ var CreateCardInputSchema = CardSchema.omit({
72
98
  id: true,
73
99
  userId: true,
74
100
  createdAt: true,
75
- updatedAt: true
101
+ updatedAt: true,
102
+ imageUrl: true,
103
+ audioUrl: true
76
104
  });
77
105
  var UpdateCardInputSchema = CreateCardInputSchema.partial();
106
+ var ListCardsSortSchema = zod.z.enum(["newest", "oldest", "due-soonest"]);
78
107
  zod.z.object({
79
108
  limit: zod.z.coerce.number().int().min(1).max(200).default(50),
80
109
  cursor: zod.z.string().optional(),
81
110
  tag: zod.z.string().optional(),
82
- source: zod.z.string().optional()
111
+ source: zod.z.string().optional(),
112
+ q: zod.z.string().min(1).max(200).optional(),
113
+ sort: ListCardsSortSchema.default("newest")
83
114
  });
84
115
  var CardStateSchema = zod.z.enum(["new", "learning", "review", "relearning"]);
85
116
  var ReviewRatingSchema = zod.z.union([zod.z.literal(1), zod.z.literal(2), zod.z.literal(3), zod.z.literal(4)]);
@@ -278,6 +309,33 @@ function createHibiClient(config) {
278
309
  if (!res.ok) throw asError(res.status, body);
279
310
  return schema.parse(body);
280
311
  }
312
+ async function requestRaw(method, path, init = {}) {
313
+ const url = new URL(`${base}${path}`);
314
+ if (init.query) {
315
+ for (const [k, v] of Object.entries(init.query)) {
316
+ if (v !== void 0) url.searchParams.set(k, String(v));
317
+ }
318
+ }
319
+ const headers = {
320
+ Authorization: `Bearer ${config.apiKey}`
321
+ };
322
+ const requestInit = { method, headers };
323
+ if (init.body !== void 0) {
324
+ headers["Content-Type"] = "application/json";
325
+ requestInit.body = JSON.stringify(init.body);
326
+ }
327
+ const res = await fetchImpl(url.toString(), requestInit);
328
+ if (!res.ok) {
329
+ const text = await res.text();
330
+ let body = text;
331
+ try {
332
+ body = JSON.parse(text);
333
+ } catch {
334
+ }
335
+ throw asError(res.status, body);
336
+ }
337
+ return res;
338
+ }
281
339
  function buildUploadForm(input, defaultName) {
282
340
  const fd = new FormData();
283
341
  if (typeof Blob !== "undefined" && input instanceof Blob) {
@@ -294,9 +352,16 @@ function createHibiClient(config) {
294
352
  const validated = CreateCardInputSchema.parse(input);
295
353
  return request("POST", "/v1/cards", CardSchema, { body: validated });
296
354
  },
297
- async list(query = { limit: 50 }) {
355
+ async list(query = { limit: 50, sort: "newest" }) {
298
356
  return request("GET", "/v1/cards", PaginatedCardSchema, {
299
- query: { limit: query.limit, cursor: query.cursor, tag: query.tag, source: query.source }
357
+ query: {
358
+ limit: query.limit,
359
+ cursor: query.cursor,
360
+ tag: query.tag,
361
+ source: query.source,
362
+ q: query.q,
363
+ sort: query.sort
364
+ }
300
365
  });
301
366
  },
302
367
  async get(id) {
@@ -390,6 +455,30 @@ function createHibiClient(config) {
390
455
  query: { from: query.from, to: query.to }
391
456
  });
392
457
  }
458
+ },
459
+ ai: {
460
+ // Discovery: is the user's OpenRouter key configured server-side?
461
+ // Hit this on app start before surfacing AI-dependent UI.
462
+ async key() {
463
+ return request("GET", "/v1/ai/key", ClientAiStatusSchema);
464
+ },
465
+ // OpenRouter chat completions, proxied. Returns the raw Response
466
+ // so the caller can stream from res.body (when stream:true) or
467
+ // call res.json() (when stream:false).
468
+ async chatCompletions(body) {
469
+ return requestRaw("POST", "/v1/ai/chat/completions", { body });
470
+ },
471
+ audio: {
472
+ async transcriptions(body) {
473
+ const res = await requestRaw("POST", "/v1/ai/audio/transcriptions", { body });
474
+ return res.json();
475
+ },
476
+ // Returns the raw audio bytes (MP3 by default).
477
+ async speech(body) {
478
+ const res = await requestRaw("POST", "/v1/ai/audio/speech", { body });
479
+ return new Uint8Array(await res.arrayBuffer());
480
+ }
481
+ }
393
482
  }
394
483
  };
395
484
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/_vendored/hibi-types/common.ts","../src/_vendored/hibi-types/account.ts","../src/_vendored/hibi-types/cards.ts","../src/_vendored/hibi-types/reviews.ts","../src/_vendored/hibi-types/sessions.ts","../src/_vendored/hibi-types/stats.ts","../src/_vendored/hibi-types/word-status.ts","../src/client.ts"],"names":["z"],"mappings":";;;;;AAEO,IAAM,UAAA,GAAaA,MAAE,IAAA,EAAK;AAE1B,IAAM,kBAAkBA,KAAA,CAAE,GAAA,CAAI,SAAS,EAAE,MAAA,EAAQ,MAAM,CAAA;AAEzBA,MAAE,MAAA,CAAO;AAAA,EAC5C,KAAA,EAAOA,KAAA,CAAE,MAAA,CAAO,MAAA,GAAS,GAAA,EAAI,CAAE,GAAA,CAAI,CAAC,CAAA,CAAE,GAAA,CAAI,GAAG,CAAA,CAAE,QAAQ,EAAE,CAAA;AAAA,EACzD,MAAA,EAAQA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AACrB,CAAC;AAIM,IAAM,eAAA,GAAkB,CAAyB,IAAA,KACtDA,KAAA,CAAE,MAAA,CAAO;AAAA,EACP,KAAA,EAAOA,KAAA,CAAE,KAAA,CAAM,IAAI,CAAA;AAAA,EACnB,UAAA,EAAYA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AACzB,CAAC,CAAA;AAEgCA,MAAE,MAAA,CAAO;AAAA,EAC1C,KAAA,EAAOA,MAAE,MAAA,CAAO;AAAA,IACd,IAAA,EAAMA,MAAE,MAAA,EAAO;AAAA,IACf,OAAA,EAASA,MAAE,MAAA,EAAO;AAAA,IAClB,OAAA,EAASA,KAAA,CAAE,OAAA,EAAQ,CAAE,QAAA;AAAS,GAC/B;AACH,CAAC;;;ACtB4BA,MAAE,MAAA,CAAO;AAAA,EACpC,EAAA,EAAI,UAAA;AAAA,EACJ,KAAA,EAAOA,MAAE,KAAA,EAAM;AAAA,EACf,SAAA,EAAW;AACb,CAAC;AAGM,IAAM,YAAA,GAAeA,MAAE,MAAA,CAAO;AAAA,EACnC,EAAA,EAAI,UAAA;AAAA,EACJ,IAAA,EAAMA,MAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA,CAAE,IAAI,EAAE,CAAA;AAAA,EAC9B,UAAA,EAAY,gBAAgB,QAAA,EAAS;AAAA,EACrC,SAAA,EAAW,eAAA;AAAA,EACX,SAAA,EAAW,gBAAgB,QAAA;AAC7B,CAAC,CAAA;AAGsCA,MAAE,MAAA,CAAO;AAAA,EAC9C,IAAA,EAAMA,MAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA,CAAE,IAAI,EAAE;AAChC,CAAC;AAGyCA,MAAE,MAAA,CAAO;AAAA,EACjD,MAAA,EAAQ,YAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA;AACZ,CAAC;ACxBM,IAAM,kBAAA,GAAqBA,MAAE,MAAA,CAAO;AAAA,EACzC,IAAA,EAAMA,MAAE,MAAA,EAAO;AAAA,EACf,OAAA,EAASA,MAAE,MAAA;AACb,CAAC,CAAA;AAGM,IAAM,gBAAA,GAAmBA,MAAE,MAAA,CAAO;AAAA,EACvC,KAAA,EAAOA,KAAAA,CAAE,MAAA,EAAO,CAAE,OAAO,CAAC,CAAA;AAAA,EAC1B,OAAA,EAASA,MAAE,MAAA,EAAO;AAAA,EAClB,aAAA,EAAeA,KAAAA,CAAE,MAAA,EAAO,CAAE,GAAA,EAAI,CAAE,GAAA,CAAI,CAAC,CAAA,CAAE,GAAA,CAAI,EAAE,CAAA,CAAE,QAAA;AACjD,CAAC,CAAA;AAGM,IAAM,UAAA,GAAaA,MAAE,MAAA,CAAO;AAAA,EACjC,EAAA,EAAI,UAAA;AAAA,EACJ,MAAA,EAAQ,UAAA;AAAA,EACR,SAAA,EAAW,eAAA;AAAA,EACX,SAAA,EAAW,eAAA;AAAA,EAEX,QAAA,EAAUA,KAAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA;AAAA,EAC1B,SAAA,EAAWA,KAAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA;AAAA,EAC3B,gBAAA,EAAkBA,KAAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA;AAAA,EAClC,QAAA,EAAUA,KAAAA,CAAE,KAAA,CAAM,kBAAkB,CAAA;AAAA,EACpC,OAAA,EAASA,MAAE,MAAA,EAAO;AAAA,EAClB,OAAA,EAASA,KAAAA,CAAE,KAAA,CAAMA,KAAAA,CAAE,QAAQ,CAAA;AAAA,EAC3B,WAAA,EAAaA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EACjC,SAAA,EAAWA,KAAAA,CAAE,KAAA,CAAM,gBAAgB,CAAA;AAAA,EAEnC,QAAA,EAAUA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EAC9B,QAAA,EAAUA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EAE9B,MAAA,EAAQA,MAAE,MAAA,EAAO;AAAA,EACjB,IAAA,EAAMA,KAAAA,CAAE,KAAA,CAAMA,KAAAA,CAAE,QAAQ;AAC1B,CAAC,CAAA;AAGM,IAAM,qBAAA,GAAwB,WAAW,IAAA,CAAK;AAAA,EACnD,EAAA,EAAI,IAAA;AAAA,EACJ,MAAA,EAAQ,IAAA;AAAA,EACR,SAAA,EAAW,IAAA;AAAA,EACX,SAAA,EAAW;AACb,CAAC,CAAA;AAGM,IAAM,qBAAA,GAAwB,sBAAsB,OAAA,EAAQ;AAG/BA,MAAE,MAAA,CAAO;AAAA,EAC3C,KAAA,EAAOA,KAAAA,CAAE,MAAA,CAAO,MAAA,GAAS,GAAA,EAAI,CAAE,GAAA,CAAI,CAAC,CAAA,CAAE,GAAA,CAAI,GAAG,CAAA,CAAE,QAAQ,EAAE,CAAA;AAAA,EACzD,MAAA,EAAQA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EAC5B,GAAA,EAAKA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EACzB,MAAA,EAAQA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AACrB,CAAC;ACpDM,IAAM,eAAA,GAAkBA,MAAE,IAAA,CAAK,CAAC,OAAO,UAAA,EAAY,QAAA,EAAU,YAAY,CAAC,CAAA;AAG1E,IAAM,kBAAA,GAAqBA,MAAE,KAAA,CAAM,CAACA,MAAE,OAAA,CAAQ,CAAC,GAAGA,KAAAA,CAAE,OAAA,CAAQ,CAAC,CAAA,EAAGA,KAAAA,CAAE,QAAQ,CAAC,CAAA,EAAGA,MAAE,OAAA,CAAQ,CAAC,CAAC,CAAC,CAAA;AAG3F,IAAM,YAAA,GAAeA,MAAE,MAAA,CAAO;AAAA,EACnC,EAAA,EAAI,UAAA;AAAA,EACJ,MAAA,EAAQ,UAAA;AAAA,EACR,MAAA,EAAQ,UAAA;AAAA,EACR,MAAA,EAAQ,kBAAA;AAAA,EACR,UAAA,EAAY,eAAA;AAAA,EACZ,WAAA,EAAaA,MAAE,MAAA,EAAO;AAAA,EACtB,aAAA,EAAeA,MAAE,MAAA,EAAO;AAAA,EACxB,WAAA,EAAa,eAAA;AAAA,EACb,UAAA,EAAY;AACd,CAAC,CAAA;AAGM,IAAM,kBAAA,GAAqBA,MAAE,MAAA,CAAO;AAAA,EACzC,MAAA,EAAQ,UAAA;AAAA,EACR,MAAA,EAAQ,UAAA;AAAA,EACR,GAAA,EAAK,eAAA;AAAA,EACL,SAAA,EAAWA,MAAE,MAAA,EAAO;AAAA,EACpB,UAAA,EAAYA,MAAE,MAAA,EAAO;AAAA,EACrB,WAAA,EAAaA,MAAE,MAAA,EAAO;AAAA,EACtB,aAAA,EAAeA,MAAE,MAAA,EAAO;AAAA,EACxB,MAAMA,KAAAA,CAAE,MAAA,EAAO,CAAE,GAAA,GAAM,WAAA,EAAY;AAAA,EACnC,QAAQA,KAAAA,CAAE,MAAA,EAAO,CAAE,GAAA,GAAM,WAAA,EAAY;AAAA,EACrC,eAAeA,KAAAA,CAAE,MAAA,EAAO,CAAE,GAAA,GAAM,WAAA,EAAY;AAAA,EAC5C,KAAA,EAAO,eAAA;AAAA,EACP,UAAA,EAAY,gBAAgB,QAAA;AAC9B,CAAC,CAAA;AAGoCA,MAAE,MAAA,CAAO;AAAA,EAC5C,KAAA,EAAOA,KAAAA,CAAE,MAAA,CAAO,MAAA,GAAS,GAAA,EAAI,CAAE,GAAA,CAAI,CAAC,CAAA,CAAE,GAAA,CAAI,GAAG,CAAA,CAAE,QAAQ,EAAE,CAAA;AAAA,EACzD,MAAA,EAAQ,gBAAgB,QAAA;AAC1B,CAAC;AAGM,IAAM,uBAAA,GAA0BA,MAAE,MAAA,CAAO;AAAA,EAC9C,MAAA,EAAQ,UAAA;AAAA,EACR,MAAA,EAAQ,kBAAA;AAAA,EACR,UAAA,EAAY,gBAAgB,QAAA;AAC9B,CAAC,CAAA;AAGM,IAAM,wBAAA,GAA2BA,MAAE,MAAA,CAAO;AAAA,EAC/C,MAAA,EAAQ,YAAA;AAAA,EACR,SAAA,EAAW;AACb,CAAC,CAAA;ACjDM,IAAM,qBAAA,GAAwBA,KAAAA,CAAE,MAAA,CAAOA,KAAAA,CAAE,MAAA,IAAUA,KAAAA,CAAE,OAAA,EAAS,CAAA,CAAE,QAAA,EAAS;AAEzE,IAAM,aAAA,GAAgBA,MAAE,MAAA,CAAO;AAAA,EACpC,EAAA,EAAI,UAAA;AAAA,EACJ,MAAA,EAAQ,UAAA;AAAA,EACR,IAAA,EAAMA,KAAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA;AAAA,EACtB,MAAA,EAAQA,KAAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA;AAAA,EACxB,SAAA,EAAW,eAAA;AAAA,EACX,OAAA,EAAS,eAAA;AAAA,EACT,YAAYA,KAAAA,CAAE,MAAA,EAAO,CAAE,GAAA,GAAM,WAAA,EAAY;AAAA,EACzC,QAAA,EAAU,qBAAA;AAAA,EACV,SAAA,EAAW;AACb,CAAC,CAAA;AAGM,IAAM,wBAAA,GAA2B,cAAc,IAAA,CAAK;AAAA,EACzD,EAAA,EAAI,IAAA;AAAA,EACJ,MAAA,EAAQ,IAAA;AAAA,EACR,SAAA,EAAW;AACb,CAAC,EAAE,MAAA,CAAO;AAAA,EACR,QAAA,EAAU,sBAAsB,QAAA;AAClC,CAAC,CAAA;AAGM,IAAM,uBAAA,GAA0BA,MAAE,MAAA,CAAO;AAAA,EAC9C,KAAA,EAAOA,KAAAA,CAAE,MAAA,CAAO,MAAA,GAAS,GAAA,EAAI,CAAE,GAAA,CAAI,CAAC,CAAA,CAAE,GAAA,CAAI,GAAG,CAAA,CAAE,QAAQ,EAAE,CAAA;AAAA,EACzD,MAAA,EAAQA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EAC5B,IAAA,EAAMA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EAC1B,MAAA,EAAQA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA;AAAA,EAE5B,IAAA,EAAMA,MAAE,GAAA,CAAI,QAAA,CAAS,EAAE,MAAA,EAAQ,IAAA,EAAM,CAAA,CAAE,QAAA,EAAS;AAAA,EAChD,EAAA,EAAIA,MAAE,GAAA,CAAI,QAAA,CAAS,EAAE,MAAA,EAAQ,IAAA,EAAM,CAAA,CAAE,QAAA;AACvC,CAAC,CAAA;AClCM,IAAM,gBAAA,GAAmBA,MAAE,MAAA,CAAO;AAAA,EACvC,IAAA,EAAMA,KAAAA,CAAE,GAAA,CAAI,IAAA,EAAK;AAAA,EACjB,OAAOA,KAAAA,CAAE,MAAA,EAAO,CAAE,GAAA,GAAM,WAAA;AAC1B,CAAC,CAAA;AAGiCA,MAAE,MAAA,CAAO;AAAA,EACzC,IAAA,EAAMA,KAAAA,CAAE,MAAA,CAAO,MAAA,EAAO,CAAE,GAAA,EAAI,CAAE,GAAA,CAAI,GAAI,CAAA,CAAE,GAAA,CAAI,IAAI;AAClD,CAAC;AAGM,IAAM,qBAAA,GAAwBA,MAAE,MAAA,CAAO;AAAA,EAC5C,IAAA,EAAMA,KAAAA,CAAE,MAAA,EAAO,CAAE,GAAA,EAAI;AAAA,EACrB,IAAA,EAAMA,KAAAA,CAAE,KAAA,CAAM,gBAAgB;AAChC,CAAC,CAAA;AAGM,IAAM,oBAAA,GAAuBA,MAAE,MAAA,CAAO;AAAA,EAC3C,cAAcA,KAAAA,CAAE,MAAA,EAAO,CAAE,GAAA,GAAM,WAAA,EAAY;AAAA,EAC3C,SAAA,EAAWA,MAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA,CAAE,IAAI,CAAC,CAAA;AAAA,EAClC,YAAYA,KAAAA,CAAE,MAAA,EAAO,CAAE,GAAA,GAAM,WAAA;AAC/B,CAAC,CAAA;AAGM,IAAM,uBAAA,GAA0BA,MAAE,MAAA,CAAO;AAAA,EAC9C,WAAA,EAAa,eAAA;AAAA,EACb,MAAA,EAAQA,KAAAA,CAAE,KAAA,CAAM,oBAAoB;AACtC,CAAC,CAAA;AAGoCA,MAAE,MAAA,CAAO;AAAA,EAC5C,IAAA,EAAMA,KAAAA,CAAE,GAAA,CAAI,IAAA,EAAK;AAAA,EACjB,EAAA,EAAIA,KAAAA,CAAE,GAAA,CAAI,IAAA;AACZ,CAAC;AAGM,IAAM,gBAAA,GAAmBA,MAAE,MAAA,CAAO;AAAA,EACvC,IAAA,EAAMA,KAAAA,CAAE,GAAA,CAAI,IAAA,EAAK;AAAA,EACjB,SAASA,KAAAA,CAAE,MAAA,EAAO,CAAE,GAAA,GAAM,WAAA,EAAY;AAAA,EACtC,OAAOA,KAAAA,CAAE,MAAA,EAAO,CAAE,GAAA,GAAM,WAAA,EAAY;AAAA,EACpC,MAAMA,KAAAA,CAAE,MAAA,EAAO,CAAE,GAAA,GAAM,WAAA,EAAY;AAAA,EACnC,MAAMA,KAAAA,CAAE,MAAA,EAAO,CAAE,GAAA,GAAM,WAAA,EAAY;AAAA,EACnC,MAAMA,KAAAA,CAAE,MAAA,EAAO,CAAE,GAAA,GAAM,WAAA;AACzB,CAAC,CAAA;AAGM,IAAM,wBAAA,GAA2BA,MAAE,MAAA,CAAO;AAAA,EAC/C,IAAA,EAAMA,KAAAA,CAAE,KAAA,CAAM,gBAAgB;AAChC,CAAC,CAAA;AC9CM,IAAM,mBAAmBA,KAAAA,CAAE,IAAA,CAAK,CAAC,UAAA,EAAY,OAAA,EAAS,SAAS,CAAC,CAAA;AAKhE,IAAM,sBAAA,GAAyBA,MAAE,MAAA,CAAO;AAAA,EAC7C,EAAA,EAAI,UAAA;AAAA,EACJ,KAAA,EAAOA,KAAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA;AAAA,EACvB,OAAA,EAASA,KAAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA;AAAA,EACzB,MAAA,EAAQ,gBAAA;AAAA,EACR,SAAA,EAAW,eAAA;AAAA,EACX,SAAA,EAAW;AACb,CAAC,CAAA;AAIM,IAAM,wBAAA,GAA2BA,MAAE,MAAA,CAAO;AAAA,EAC/C,KAAA,EAAOA,KAAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA;AAAA,EACvB,OAAA,EAASA,KAAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA;AAAA,EACzB,MAAA,EAAQ,iBAAiB,QAAA;AAC3B,CAAC,CAAA;AAOM,IAAM,eAAA,GAAkBA,MAAE,MAAA,CAAO;AAAA,EACtC,KAAA,EAAOA,MAAE,MAAA,EAAO;AAAA,EAChB,OAAA,EAASA,MAAE,MAAA,EAAO;AAAA,EAClB,MAAA,EAAQ,gBAAA;AAAA,EACR,QAAQA,KAAAA,CAAE,IAAA,CAAK,CAAC,QAAA,EAAU,KAAK,CAAC,CAAA;AAAA,EAChC,MAAA,EAAQ,WAAW,QAAA,EAAS;AAAA,EAC5B,cAAcA,KAAAA,CAAE,MAAA,EAAO,CAAE,GAAA,GAAM,QAAA,EAAS;AAAA,EACxC,SAAA,EAAW;AACb,CAAC,CAAA;;;ACAD,IAAM,mBAAA,GAAsB,gBAAgB,UAAU,CAAA;AACtD,IAAM,sBAAA,GAAyB,gBAAgB,aAAa,CAAA;AAC5D,IAAM,2BAAA,GAA8B,gBAAgB,sBAAsB,CAAA;AAC1E,IAAM,wBAAA,GAA2B,gBAAgB,eAAe,CAAA;AAChE,IAAM,0BAAA,GAA6B,uBAAuB,QAAA,EAAS;AACnE,IAAM,iBAAA,GAAoBA,MAAE,MAAA,CAAO;AAAA,EACjC,OAAOA,KAAAA,CAAE,KAAA;AAAA,IACPA,KAAAA,CAAE,OAAO,EAAE,IAAA,EAAM,YAAY,SAAA,EAAW,wBAAA,CAAyB,KAAA,CAAM,SAAA,EAAW;AAAA;AAEtF,CAAC,CAAA;AACD,IAAM,oBAAA,GAAuBA,MAAE,MAAA,CAAO,EAAE,KAAKA,KAAAA,CAAE,MAAA,IAAU,CAAA;AAYzD,SAAS,OAAA,CAAQ,MAAA,EAAgB,IAAA,EAAe,OAAA,EAAmC;AACjF,EAAA,MAAM,MAAM,IAAI,KAAA,CAAM,OAAA,IAAW,CAAA,gBAAA,EAAmB,MAAM,CAAA,CAAE,CAAA;AAC5D,EAAA,GAAA,CAAI,MAAA,GAAS,MAAA;AACb,EAAA,GAAA,CAAI,IAAA,GAAO,IAAA;AACX,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,WAAW,KAAA,EAAmC;AACrD,EAAA,OAAO,OAAO,QAAA,KAAa,WAAA,IAAe,KAAA,YAAiB,QAAA;AAC7D;AAEO,SAAS,iBAAiB,MAAA,EAA0B;AACzD,EAAA,MAAM,SAAA,GAAY,OAAO,KAAA,IAAS,KAAA;AAClC,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,OAAA,CAAQ,OAAA,CAAQ,QAAQ,EAAE,CAAA;AAE9C,EAAA,eAAe,QACb,MAAA,EACA,IAAA,EACA,MAAA,EACA,IAAA,GAGI,EAAC,EACO;AACZ,IAAA,MAAM,MAAM,IAAI,GAAA,CAAI,GAAG,IAAI,CAAA,EAAG,IAAI,CAAA,CAAE,CAAA;AACpC,IAAA,IAAI,KAAK,KAAA,EAAO;AACd,MAAA,KAAA,MAAW,CAAC,GAAG,CAAC,CAAA,IAAK,OAAO,OAAA,CAAQ,IAAA,CAAK,KAAK,CAAA,EAAG;AAC/C,QAAA,IAAI,CAAA,KAAM,QAAW,GAAA,CAAI,YAAA,CAAa,IAAI,CAAA,EAAG,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,MACxD;AAAA,IACF;AAEA,IAAA,MAAM,OAAA,GAAkC;AAAA,MACtC,aAAA,EAAe,CAAA,OAAA,EAAU,MAAA,CAAO,MAAM,CAAA;AAAA,KACxC;AACA,IAAA,MAAM,WAAA,GAA2B,EAAE,MAAA,EAAQ,OAAA,EAAQ;AACnD,IAAA,IAAI,IAAA,CAAK,SAAS,MAAA,EAAW;AAC3B,MAAA,IAAI,UAAA,CAAW,IAAA,CAAK,IAAI,CAAA,EAAG;AAGzB,QAAA,WAAA,CAAY,OAAO,IAAA,CAAK,IAAA;AAAA,MAC1B,CAAA,MAAO;AACL,QAAA,OAAA,CAAQ,cAAc,CAAA,GAAI,kBAAA;AAC1B,QAAA,WAAA,CAAY,IAAA,GAAO,IAAA,CAAK,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA;AAAA,MAC7C;AAAA,IACF;AAEA,IAAA,MAAM,MAAM,MAAM,SAAA,CAAU,GAAA,CAAI,QAAA,IAAY,WAAW,CAAA;AAEvD,IAAA,IAAI,GAAA,CAAI,MAAA,KAAW,GAAA,EAAK,OAAO,MAAA;AAE/B,IAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,IAAA,MAAM,WAAA,GAAc,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,cAAc,CAAA,IAAK,EAAA;AACvD,IAAA,IAAI,IAAA,GAAgB,IAAA;AACpB,IAAA,IAAI,IAAA,EAAM;AACR,MAAA,IAAI,WAAA,CAAY,QAAA,CAAS,kBAAkB,CAAA,EAAG;AAC5C,QAAA,IAAI;AACF,UAAA,IAAA,GAAO,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,QACxB,SAAS,GAAA,EAAK;AACZ,UAAA,MAAM,OAAA;AAAA,YACJ,GAAA,CAAI,MAAA;AAAA,YACJ,EAAE,OAAA,EAAS,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,GAAG,CAAA,EAAG,UAAA,EAAY,MAAA,CAAO,GAAG,CAAA,EAAE;AAAA,YACvD,CAAA,SAAA,EAAY,GAAA,CAAI,MAAM,CAAA,sBAAA,EAAyB,GAAA,CAAI,QAAA,EAAU,CAAA,mBAAA,EAAsB,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,GAAG,CAAC,CAAA,CAAA;AAAA,WACvG;AAAA,QACF;AAAA,MACF,CAAA,MAAO;AAIL,QAAA,MAAM,OAAA;AAAA,UACJ,GAAA,CAAI,MAAA;AAAA,UACJ,EAAE,OAAA,EAAS,IAAA,CAAK,MAAM,CAAA,EAAG,GAAG,GAAG,WAAA,EAAY;AAAA,UAC3C,CAAA,SAAA,EAAY,GAAA,CAAI,MAAM,CAAA,qBAAA,EAAwB,IAAI,QAAA,EAAU,CAAA,SAAA,EAAY,WAAA,IAAe,sBAAsB,CAAA,mBAAA,EAAsB,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,GAAG,CAAC,CAAA,CAAA;AAAA,SACvJ;AAAA,MACF;AAAA,IACF;AAEA,IAAA,IAAI,CAAC,GAAA,CAAI,EAAA,QAAU,OAAA,CAAQ,GAAA,CAAI,QAAQ,IAAI,CAAA;AAC3C,IAAA,OAAO,MAAA,CAAO,MAAM,IAAI,CAAA;AAAA,EAC1B;AAEA,EAAA,SAAS,eAAA,CAAgB,OAAoB,WAAA,EAA+B;AAC1E,IAAA,MAAM,EAAA,GAAK,IAAI,QAAA,EAAS;AACxB,IAAA,IAAI,OAAO,IAAA,KAAS,WAAA,IAAe,KAAA,YAAiB,IAAA,EAAM;AAExD,MAAA,MAAM,IAAA,GAAO,UAAU,KAAA,IAAS,OAAO,MAAM,IAAA,KAAS,QAAA,GAAW,MAAM,IAAA,GAAO,WAAA;AAC9E,MAAA,EAAA,CAAG,MAAA,CAAO,MAAA,EAAQ,KAAA,EAAO,IAAI,CAAA;AAAA,IAC/B,CAAA,MAAO;AAGL,MAAA,EAAA,CAAG,MAAA,CAAO,QAAQ,KAAwB,CAAA;AAAA,IAC5C;AACA,IAAA,OAAO,EAAA;AAAA,EACT;AAEA,EAAA,OAAO;AAAA,IACL,KAAA,EAAO;AAAA,MACL,MAAM,OAAO,KAAA,EAAwB;AACnC,QAAA,MAAM,SAAA,GAAY,qBAAA,CAAsB,KAAA,CAAM,KAAK,CAAA;AACnD,QAAA,OAAO,QAAQ,MAAA,EAAQ,WAAA,EAAa,YAAY,EAAE,IAAA,EAAM,WAAW,CAAA;AAAA,MACrE,CAAA;AAAA,MACA,MAAM,IAAA,CAAK,KAAA,GAAwB,EAAE,KAAA,EAAO,IAAG,EAAG;AAChD,QAAA,OAAO,OAAA,CAAQ,KAAA,EAAO,WAAA,EAAa,mBAAA,EAAqB;AAAA,UACtD,KAAA,EAAO,EAAE,KAAA,EAAO,KAAA,CAAM,KAAA,EAAO,MAAA,EAAQ,KAAA,CAAM,MAAA,EAAQ,GAAA,EAAK,KAAA,CAAM,GAAA,EAAK,MAAA,EAAQ,MAAM,MAAA;AAAO,SACzF,CAAA;AAAA,MACH,CAAA;AAAA,MACA,MAAM,IAAI,EAAA,EAAY;AACpB,QAAA,OAAO,OAAA,CAAQ,KAAA,EAAO,CAAA,UAAA,EAAa,EAAE,IAAI,UAAU,CAAA;AAAA,MACrD,CAAA;AAAA,MACA,MAAM,MAAA,CAAO,EAAA,EAAY,KAAA,EAAwB;AAC/C,QAAA,MAAM,SAAA,GAAY,qBAAA,CAAsB,KAAA,CAAM,KAAK,CAAA;AACnD,QAAA,OAAO,OAAA,CAAQ,SAAS,CAAA,UAAA,EAAa,EAAE,IAAI,UAAA,EAAY,EAAE,IAAA,EAAM,SAAA,EAAW,CAAA;AAAA,MAC5E,CAAA;AAAA,MACA,MAAM,OAAO,EAAA,EAA2B;AACtC,QAAA,MAAM,QAAQ,QAAA,EAAU,CAAA,UAAA,EAAa,EAAE,CAAA,CAAA,EAAIA,KAAAA,CAAE,SAAS,CAAA;AAAA,MACxD;AAAA,KACF;AAAA,IAEA,OAAA,EAAS;AAAA,MACP,MAAM,MAAM,KAAA,EAAoB;AAC9B,QAAA,OAAO,OAAA,CAAQ,MAAA,EAAQ,mBAAA,EAAqB,oBAAA,EAAsB;AAAA,UAChE,IAAA,EAAM,eAAA,CAAgB,KAAA,EAAO,UAAU;AAAA,SACxC,CAAA;AAAA,MACH,CAAA;AAAA,MACA,MAAM,MAAM,KAAA,EAAoB;AAC9B,QAAA,OAAO,OAAA,CAAQ,MAAA,EAAQ,mBAAA,EAAqB,oBAAA,EAAsB;AAAA,UAChE,IAAA,EAAM,eAAA,CAAgB,KAAA,EAAO,WAAW;AAAA,SACzC,CAAA;AAAA,MACH;AAAA,KACF;AAAA,IAEA,QAAA,EAAU;AAAA,MACR,MAAM,OAAO,KAAA,EAA2B;AACtC,QAAA,MAAM,SAAA,GAAY,wBAAA,CAAyB,KAAA,CAAM,KAAK,CAAA;AACtD,QAAA,OAAO,QAAQ,MAAA,EAAQ,cAAA,EAAgB,eAAe,EAAE,IAAA,EAAM,WAAW,CAAA;AAAA,MAC3E,CAAA;AAAA,MACA,MAAM,IAAA,CAAK,KAAA,GAA2B,EAAE,KAAA,EAAO,IAAG,EAAG;AACnD,QAAA,MAAM,SAAA,GAAY,uBAAA,CAAwB,KAAA,CAAM,KAAK,CAAA;AACrD,QAAA,OAAO,OAAA,CAAQ,KAAA,EAAO,cAAA,EAAgB,sBAAA,EAAwB;AAAA,UAC5D,KAAA,EAAO;AAAA,YACL,OAAO,SAAA,CAAU,KAAA;AAAA,YACjB,QAAQ,SAAA,CAAU,MAAA;AAAA,YAClB,MAAM,SAAA,CAAU,IAAA;AAAA,YAChB,QAAQ,SAAA,CAAU,MAAA;AAAA,YAClB,MAAM,SAAA,CAAU,IAAA;AAAA,YAChB,IAAI,SAAA,CAAU;AAAA;AAChB,SACD,CAAA;AAAA,MACH;AAAA,KACF;AAAA,IAEA,OAAA,EAAS;AAAA,MACP,MAAM,GAAA,CAAI,KAAA,GAA6C,EAAC,EAAG;AACzD,QAAA,OAAO,OAAA,CAAQ,KAAA,EAAO,iBAAA,EAAmB,iBAAA,EAAmB;AAAA,UAC1D,OAAO,EAAE,KAAA,EAAO,MAAM,KAAA,EAAO,MAAA,EAAQ,MAAM,MAAA;AAAO,SACnD,CAAA;AAAA,MACH,CAAA;AAAA,MACA,MAAM,OAAO,KAAA,EAA0B;AACrC,QAAA,MAAM,SAAA,GAAY,uBAAA,CAAwB,KAAA,CAAM,KAAK,CAAA;AACrD,QAAA,OAAO,QAAQ,MAAA,EAAQ,aAAA,EAAe,0BAA0B,EAAE,IAAA,EAAM,WAAW,CAAA;AAAA,MACrF;AAAA,KACF;AAAA,IAEA,UAAA,EAAY;AAAA;AAAA,MAEV,MAAM,IAAI,KAAA,EAA2B;AACnC,QAAA,MAAM,SAAA,GAAY,wBAAA,CAAyB,KAAA,CAAM,KAAK,CAAA;AACtD,QAAA,OAAO,OAAA,CAAQ,KAAA,EAAO,iBAAA,EAAmB,0BAAA,EAA4B;AAAA,UACnE,IAAA,EAAM;AAAA,SACP,CAAA;AAAA,MACH,CAAA;AAAA;AAAA,MAEA,MAAM,IAAA,CAAK,KAAA,GAAyB,EAAE,KAAA,EAAO,IAAG,EAAG;AACjD,QAAA,OAAO,OAAA,CAAQ,KAAA,EAAO,iBAAA,EAAmB,2BAAA,EAA6B;AAAA,UACpE,OAAO,EAAE,KAAA,EAAO,MAAM,KAAA,EAAO,MAAA,EAAQ,MAAM,MAAA;AAAO,SACnD,CAAA;AAAA,MACH;AAAA,KACF;AAAA,IAEA,UAAA,EAAY;AAAA;AAAA;AAAA,MAGV,MAAM,IAAA,CAAK,KAAA,GAAyB,EAAE,KAAA,EAAO,IAAG,EAAG;AACjD,QAAA,OAAO,OAAA,CAAQ,KAAA,EAAO,iBAAA,EAAmB,wBAAA,EAA0B;AAAA,UACjE,OAAO,EAAE,KAAA,EAAO,MAAM,KAAA,EAAO,MAAA,EAAQ,MAAM,MAAA;AAAO,SACnD,CAAA;AAAA,MACH;AAAA,KACF;AAAA,IAEA,KAAA,EAAO;AAAA,MACL,MAAM,QAAQ,KAAA,EAAqB;AACjC,QAAA,OAAO,OAAA,CAAQ,KAAA,EAAO,mBAAA,EAAqB,qBAAA,EAAuB;AAAA,UAChE,KAAA,EAAO,EAAE,IAAA,EAAM,KAAA,CAAM,IAAA;AAAK,SAC3B,CAAA;AAAA,MACH,CAAA;AAAA,MACA,MAAM,SAAA,GAAY;AAChB,QAAA,OAAO,OAAA,CAAQ,KAAA,EAAO,qBAAA,EAAuB,uBAAuB,CAAA;AAAA,MACtE,CAAA;AAAA,MACA,MAAM,MAAM,KAAA,EAAwB;AAClC,QAAA,OAAO,OAAA,CAAQ,KAAA,EAAO,iBAAA,EAAmB,wBAAA,EAA0B;AAAA,UACjE,OAAO,EAAE,IAAA,EAAM,MAAM,IAAA,EAAM,EAAA,EAAI,MAAM,EAAA;AAAG,SACzC,CAAA;AAAA,MACH;AAAA;AACF,GACF;AACF","file":"index.cjs","sourcesContent":["import { z } from \"zod\";\n\nexport const UUIDSchema = z.uuid();\n\nexport const TimestampSchema = z.iso.datetime({ offset: true });\n\nexport const PaginationQuerySchema = z.object({\n limit: z.coerce.number().int().min(1).max(200).default(50),\n cursor: z.string().optional(),\n});\n\nexport type PaginationQuery = z.infer<typeof PaginationQuerySchema>;\n\nexport const PaginatedSchema = <T extends z.ZodTypeAny>(item: T) =>\n z.object({\n items: z.array(item),\n nextCursor: z.string().nullable(),\n });\n\nexport const ErrorResponseSchema = z.object({\n error: z.object({\n code: z.string(),\n message: z.string(),\n details: z.unknown().optional(),\n }),\n});\n\nexport type ErrorResponse = z.infer<typeof ErrorResponseSchema>;\n","import { z } from \"zod\";\nimport { TimestampSchema, UUIDSchema } from \"./common.ts\";\n\nexport const AccountSchema = z.object({\n id: UUIDSchema,\n email: z.email(),\n createdAt: TimestampSchema,\n});\nexport type Account = z.infer<typeof AccountSchema>;\n\nexport const ApiKeySchema = z.object({\n id: UUIDSchema,\n name: z.string().min(1).max(80),\n lastUsedAt: TimestampSchema.nullable(),\n createdAt: TimestampSchema,\n revokedAt: TimestampSchema.nullable(),\n});\nexport type ApiKey = z.infer<typeof ApiKeySchema>;\n\nexport const CreateApiKeyInputSchema = z.object({\n name: z.string().min(1).max(80),\n});\nexport type CreateApiKeyInput = z.infer<typeof CreateApiKeyInputSchema>;\n\nexport const CreateApiKeyResponseSchema = z.object({\n apiKey: ApiKeySchema,\n rawKey: z.string(),\n});\nexport type CreateApiKeyResponse = z.infer<typeof CreateApiKeyResponseSchema>;\n","import { z } from \"zod\";\nimport { TimestampSchema, UUIDSchema } from \"./common.ts\";\n\nexport const FuriganaPairSchema = z.object({\n base: z.string(),\n reading: z.string(),\n});\nexport type FuriganaPair = z.infer<typeof FuriganaPairSchema>;\n\nexport const KanjiEntrySchema = z.object({\n kanji: z.string().length(1),\n meaning: z.string(),\n wanikaniLevel: z.number().int().min(1).max(60).nullable(),\n});\nexport type KanjiEntry = z.infer<typeof KanjiEntrySchema>;\n\nexport const CardSchema = z.object({\n id: UUIDSchema,\n userId: UUIDSchema,\n createdAt: TimestampSchema,\n updatedAt: TimestampSchema,\n\n sentence: z.string().min(1),\n focusWord: z.string().min(1),\n focusWordReading: z.string().min(1),\n furigana: z.array(FuriganaPairSchema),\n english: z.string(),\n glosses: z.array(z.string()),\n grammarNote: z.string().nullable(),\n kanjiList: z.array(KanjiEntrySchema),\n\n imageKey: z.string().nullable(),\n audioKey: z.string().nullable(),\n\n source: z.string(),\n tags: z.array(z.string()),\n});\nexport type Card = z.infer<typeof CardSchema>;\n\nexport const CreateCardInputSchema = CardSchema.omit({\n id: true,\n userId: true,\n createdAt: true,\n updatedAt: true,\n});\nexport type CreateCardInput = z.infer<typeof CreateCardInputSchema>;\n\nexport const UpdateCardInputSchema = CreateCardInputSchema.partial();\nexport type UpdateCardInput = z.infer<typeof UpdateCardInputSchema>;\n\nexport const ListCardsQuerySchema = z.object({\n limit: z.coerce.number().int().min(1).max(200).default(50),\n cursor: z.string().optional(),\n tag: z.string().optional(),\n source: z.string().optional(),\n});\nexport type ListCardsQuery = z.infer<typeof ListCardsQuerySchema>;\n","import { z } from \"zod\";\nimport { TimestampSchema, UUIDSchema } from \"./common.ts\";\n\nexport const CardStateSchema = z.enum([\"new\", \"learning\", \"review\", \"relearning\"]);\nexport type CardStateValue = z.infer<typeof CardStateSchema>;\n\nexport const ReviewRatingSchema = z.union([z.literal(1), z.literal(2), z.literal(3), z.literal(4)]);\nexport type ReviewRating = z.infer<typeof ReviewRatingSchema>;\n\nexport const ReviewSchema = z.object({\n id: UUIDSchema,\n userId: UUIDSchema,\n cardId: UUIDSchema,\n rating: ReviewRatingSchema,\n reviewedAt: TimestampSchema,\n elapsedDays: z.number(),\n scheduledDays: z.number(),\n stateBefore: CardStateSchema,\n stateAfter: CardStateSchema,\n});\nexport type Review = z.infer<typeof ReviewSchema>;\n\nexport const CardStateRowSchema = z.object({\n cardId: UUIDSchema,\n userId: UUIDSchema,\n due: TimestampSchema,\n stability: z.number(),\n difficulty: z.number(),\n elapsedDays: z.number(),\n scheduledDays: z.number(),\n reps: z.number().int().nonnegative(),\n lapses: z.number().int().nonnegative(),\n learningSteps: z.number().int().nonnegative(),\n state: CardStateSchema,\n lastReview: TimestampSchema.nullable(),\n});\nexport type CardStateRow = z.infer<typeof CardStateRowSchema>;\n\nexport const DueReviewsQuerySchema = z.object({\n limit: z.coerce.number().int().min(1).max(200).default(50),\n before: TimestampSchema.optional(),\n});\nexport type DueReviewsQuery = z.infer<typeof DueReviewsQuerySchema>;\n\nexport const SubmitReviewInputSchema = z.object({\n cardId: UUIDSchema,\n rating: ReviewRatingSchema,\n reviewedAt: TimestampSchema.optional(),\n});\nexport type SubmitReviewInput = z.infer<typeof SubmitReviewInputSchema>;\n\nexport const SubmitReviewResultSchema = z.object({\n review: ReviewSchema,\n cardState: CardStateRowSchema,\n});\nexport type SubmitReviewResult = z.infer<typeof SubmitReviewResultSchema>;\n","import { z } from \"zod\";\nimport { TimestampSchema, UUIDSchema } from \"./common.ts\";\n\n// Free-form per-app context (e.g. { trackId } for Hibi Koe). Keep as\n// a record so future apps can attach their own keys without a type bump.\nexport const SessionMetadataSchema = z.record(z.string(), z.unknown()).nullable();\n\nexport const SessionSchema = z.object({\n id: UUIDSchema,\n userId: UUIDSchema,\n kind: z.string().min(1),\n source: z.string().min(1),\n startedAt: TimestampSchema,\n endedAt: TimestampSchema,\n durationMs: z.number().int().nonnegative(),\n metadata: SessionMetadataSchema,\n createdAt: TimestampSchema,\n});\nexport type Session = z.infer<typeof SessionSchema>;\n\nexport const CreateSessionInputSchema = SessionSchema.omit({\n id: true,\n userId: true,\n createdAt: true,\n}).extend({\n metadata: SessionMetadataSchema.optional(),\n});\nexport type CreateSessionInput = z.infer<typeof CreateSessionInputSchema>;\n\nexport const ListSessionsQuerySchema = z.object({\n limit: z.coerce.number().int().min(1).max(200).default(50),\n cursor: z.string().optional(),\n kind: z.string().optional(),\n source: z.string().optional(),\n // Inclusive lower bound, exclusive upper. Both ISO-8601 timestamps.\n from: z.iso.datetime({ offset: true }).optional(),\n to: z.iso.datetime({ offset: true }).optional(),\n});\nexport type ListSessionsQuery = z.infer<typeof ListSessionsQuerySchema>;\n","import { z } from \"zod\";\nimport { TimestampSchema } from \"./common.ts\";\n\nexport const HeatmapDaySchema = z.object({\n date: z.iso.date(),\n count: z.number().int().nonnegative(),\n});\nexport type HeatmapDay = z.infer<typeof HeatmapDaySchema>;\n\nexport const HeatmapQuerySchema = z.object({\n year: z.coerce.number().int().min(2000).max(2100),\n});\nexport type HeatmapQuery = z.infer<typeof HeatmapQuerySchema>;\n\nexport const HeatmapResponseSchema = z.object({\n year: z.number().int(),\n days: z.array(HeatmapDaySchema),\n});\nexport type HeatmapResponse = z.infer<typeof HeatmapResponseSchema>;\n\nexport const RetentionPointSchema = z.object({\n intervalDays: z.number().int().nonnegative(),\n retention: z.number().min(0).max(1),\n sampleSize: z.number().int().nonnegative(),\n});\nexport type RetentionPoint = z.infer<typeof RetentionPointSchema>;\n\nexport const RetentionResponseSchema = z.object({\n generatedAt: TimestampSchema,\n points: z.array(RetentionPointSchema),\n});\nexport type RetentionResponse = z.infer<typeof RetentionResponseSchema>;\n\nexport const DailyCountQuerySchema = z.object({\n from: z.iso.date(),\n to: z.iso.date(),\n});\nexport type DailyCountQuery = z.infer<typeof DailyCountQuerySchema>;\n\nexport const DailyCountSchema = z.object({\n date: z.iso.date(),\n reviews: z.number().int().nonnegative(),\n again: z.number().int().nonnegative(),\n hard: z.number().int().nonnegative(),\n good: z.number().int().nonnegative(),\n easy: z.number().int().nonnegative(),\n});\nexport type DailyCount = z.infer<typeof DailyCountSchema>;\n\nexport const DailyCountResponseSchema = z.object({\n days: z.array(DailyCountSchema),\n});\nexport type DailyCountResponse = z.infer<typeof DailyCountResponseSchema>;\n","import { z } from \"zod\";\nimport { TimestampSchema, UUIDSchema } from \"./common.ts\";\n\n// Three writeable values. 'unknown' is the implicit default and is\n// represented by the absence of a row, never stored explicitly.\nexport const WordStatusSchema = z.enum([\"learning\", \"known\", \"ignored\"]);\nexport type WordStatus = z.infer<typeof WordStatusSchema>;\n\n// Manual word-status row as the user set it. (lemma, reading) is unique\n// per-user; updating with the same key overwrites status + updatedAt.\nexport const ManualWordStatusSchema = z.object({\n id: UUIDSchema,\n lemma: z.string().min(1),\n reading: z.string().min(1),\n status: WordStatusSchema,\n createdAt: TimestampSchema,\n updatedAt: TimestampSchema,\n});\nexport type ManualWordStatus = z.infer<typeof ManualWordStatusSchema>;\n\n// PUT /v1/word-status body. status: null deletes the row.\nexport const SetWordStatusInputSchema = z.object({\n lemma: z.string().min(1),\n reading: z.string().min(1),\n status: WordStatusSchema.nullable(),\n});\nexport type SetWordStatusInput = z.infer<typeof SetWordStatusInputSchema>;\n\n// One row in the merged /v1/known-words response. source distinguishes\n// manual marks from SRS-derived classifications. When source is 'srs',\n// cardId + intervalDays are populated; clients should treat the status\n// as read-only and tell users to adjust by reviewing the card.\nexport const KnownWordSchema = z.object({\n lemma: z.string(),\n reading: z.string(),\n status: WordStatusSchema,\n source: z.enum([\"manual\", \"srs\"]),\n cardId: UUIDSchema.nullable(),\n intervalDays: z.number().int().nullable(),\n updatedAt: TimestampSchema,\n});\nexport type KnownWord = z.infer<typeof KnownWordSchema>;\n","import { z } from \"zod\";\nimport {\n CardSchema,\n type CreateCardInput,\n CreateCardInputSchema,\n type DailyCountQuery,\n DailyCountResponseSchema,\n type HeatmapQuery,\n HeatmapResponseSchema,\n KnownWordSchema,\n type ListCardsQuery,\n ManualWordStatusSchema,\n PaginatedSchema,\n type PaginationQuery,\n RetentionResponseSchema,\n CreateSessionInputSchema,\n type CreateSessionInput,\n type SetWordStatusInput,\n SetWordStatusInputSchema,\n ListSessionsQuerySchema,\n type ListSessionsQuery,\n SessionSchema,\n type SubmitReviewInput,\n SubmitReviewInputSchema,\n SubmitReviewResultSchema,\n type UpdateCardInput,\n UpdateCardInputSchema,\n} from \"./_vendored/hibi-types/index.ts\";\n\nexport interface HibiClientConfig {\n apiKey: string;\n baseUrl: string;\n fetch?: typeof fetch;\n}\n\nexport interface HibiClientError extends Error {\n status: number;\n body: unknown;\n}\n\nconst PaginatedCardSchema = PaginatedSchema(CardSchema);\nconst PaginatedSessionSchema = PaginatedSchema(SessionSchema);\nconst PaginatedManualStatusSchema = PaginatedSchema(ManualWordStatusSchema);\nconst PaginatedKnownWordSchema = PaginatedSchema(KnownWordSchema);\nconst NullableManualStatusSchema = ManualWordStatusSchema.nullable();\nconst DueResponseSchema = z.object({\n items: z.array(\n z.object({ card: CardSchema, cardState: SubmitReviewResultSchema.shape.cardState }),\n ),\n});\nconst UploadResponseSchema = z.object({ key: z.string() });\n\n// React-Native-style file reference. RN's FormData.append accepts this\n// shape directly; we type it explicitly so consumers can build it\n// without depending on RN-specific globals.\nexport type RNFileRef = { uri: string; name: string; type: string };\n\n// What client.uploads.* accepts. On web pass a Blob/File; on RN pass an\n// RNFileRef. In both cases the SDK builds the multipart body.\nexport type UploadInput = Blob | RNFileRef;\nexport type AudioUploadInput = UploadInput;\n\nfunction asError(status: number, body: unknown, message?: string): HibiClientError {\n const err = new Error(message ?? `Hibi API error: ${status}`) as HibiClientError;\n err.status = status;\n err.body = body;\n return err;\n}\n\nfunction isFormData(value: unknown): value is FormData {\n return typeof FormData !== \"undefined\" && value instanceof FormData;\n}\n\nexport function createHibiClient(config: HibiClientConfig) {\n const fetchImpl = config.fetch ?? fetch;\n const base = config.baseUrl.replace(/\\/+$/, \"\");\n\n async function request<T>(\n method: string,\n path: string,\n schema: z.ZodType<T>,\n init: {\n body?: unknown;\n query?: Record<string, string | number | undefined>;\n } = {},\n ): Promise<T> {\n const url = new URL(`${base}${path}`);\n if (init.query) {\n for (const [k, v] of Object.entries(init.query)) {\n if (v !== undefined) url.searchParams.set(k, String(v));\n }\n }\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${config.apiKey}`,\n };\n const requestInit: RequestInit = { method, headers };\n if (init.body !== undefined) {\n if (isFormData(init.body)) {\n // Don't set Content-Type for multipart — the runtime appends\n // the correct boundary. RN in particular breaks if we set it.\n requestInit.body = init.body;\n } else {\n headers[\"Content-Type\"] = \"application/json\";\n requestInit.body = JSON.stringify(init.body);\n }\n }\n\n const res = await fetchImpl(url.toString(), requestInit);\n\n if (res.status === 204) return undefined as T;\n\n const text = await res.text();\n const contentType = res.headers.get(\"content-type\") ?? \"\";\n let body: unknown = null;\n if (text) {\n if (contentType.includes(\"application/json\")) {\n try {\n body = JSON.parse(text);\n } catch (err) {\n throw asError(\n res.status,\n { rawText: text.slice(0, 500), parseError: String(err) },\n `Hibi API ${res.status}: malformed JSON from ${url.toString()} (first 200 chars: ${text.slice(0, 200)})`,\n );\n }\n } else {\n // Non-JSON response — almost always means we hit a misrouted host\n // (Vercel 404 wall, gateway HTML, captive portal). Surface the\n // first chunk of the body so the caller knows where to look.\n throw asError(\n res.status,\n { rawText: text.slice(0, 500), contentType },\n `Hibi API ${res.status}: expected JSON from ${url.toString()} but got ${contentType || \"unknown content-type\"} (first 200 chars: ${text.slice(0, 200)})`,\n );\n }\n }\n\n if (!res.ok) throw asError(res.status, body);\n return schema.parse(body);\n }\n\n function buildUploadForm(input: UploadInput, defaultName: string): FormData {\n const fd = new FormData();\n if (typeof Blob !== \"undefined\" && input instanceof Blob) {\n // Blob/File on web/node20+. Pass a name so the server sees a filename.\n const name = \"name\" in input && typeof input.name === \"string\" ? input.name : defaultName;\n fd.append(\"file\", input, name);\n } else {\n // RN file ref. The cast is unavoidable: RN's FormData accepts this\n // shape but the lib.dom.d.ts FormData type doesn't model it.\n fd.append(\"file\", input as unknown as Blob);\n }\n return fd;\n }\n\n return {\n cards: {\n async create(input: CreateCardInput) {\n const validated = CreateCardInputSchema.parse(input);\n return request(\"POST\", \"/v1/cards\", CardSchema, { body: validated });\n },\n async list(query: ListCardsQuery = { limit: 50 }) {\n return request(\"GET\", \"/v1/cards\", PaginatedCardSchema, {\n query: { limit: query.limit, cursor: query.cursor, tag: query.tag, source: query.source },\n });\n },\n async get(id: string) {\n return request(\"GET\", `/v1/cards/${id}`, CardSchema);\n },\n async update(id: string, input: UpdateCardInput) {\n const validated = UpdateCardInputSchema.parse(input);\n return request(\"PATCH\", `/v1/cards/${id}`, CardSchema, { body: validated });\n },\n async remove(id: string): Promise<void> {\n await request(\"DELETE\", `/v1/cards/${id}`, z.unknown());\n },\n },\n\n uploads: {\n async audio(input: UploadInput) {\n return request(\"POST\", \"/v1/uploads/audio\", UploadResponseSchema, {\n body: buildUploadForm(input, \"clip.m4a\"),\n });\n },\n async image(input: UploadInput) {\n return request(\"POST\", \"/v1/uploads/image\", UploadResponseSchema, {\n body: buildUploadForm(input, \"image.jpg\"),\n });\n },\n },\n\n sessions: {\n async create(input: CreateSessionInput) {\n const validated = CreateSessionInputSchema.parse(input);\n return request(\"POST\", \"/v1/sessions\", SessionSchema, { body: validated });\n },\n async list(query: ListSessionsQuery = { limit: 50 }) {\n const validated = ListSessionsQuerySchema.parse(query);\n return request(\"GET\", \"/v1/sessions\", PaginatedSessionSchema, {\n query: {\n limit: validated.limit,\n cursor: validated.cursor,\n kind: validated.kind,\n source: validated.source,\n from: validated.from,\n to: validated.to,\n },\n });\n },\n },\n\n reviews: {\n async due(query: { limit?: number; before?: string } = {}) {\n return request(\"GET\", \"/v1/reviews/due\", DueResponseSchema, {\n query: { limit: query.limit, before: query.before },\n });\n },\n async submit(input: SubmitReviewInput) {\n const validated = SubmitReviewInputSchema.parse(input);\n return request(\"POST\", \"/v1/reviews\", SubmitReviewResultSchema, { body: validated });\n },\n },\n\n wordStatus: {\n // Upsert (lemma, reading) for the caller; pass status: null to delete.\n async set(input: SetWordStatusInput) {\n const validated = SetWordStatusInputSchema.parse(input);\n return request(\"PUT\", \"/v1/word-status\", NullableManualStatusSchema, {\n body: validated,\n });\n },\n // Paginated list of just the manual rows (no SRS rows).\n async list(query: PaginationQuery = { limit: 50 }) {\n return request(\"GET\", \"/v1/word-status\", PaginatedManualStatusSchema, {\n query: { limit: query.limit, cursor: query.cursor },\n });\n },\n },\n\n knownWords: {\n // Merged manual + SRS classifications. Single source of truth for\n // the underline-by-status view in reading clients.\n async list(query: PaginationQuery = { limit: 50 }) {\n return request(\"GET\", \"/v1/known-words\", PaginatedKnownWordSchema, {\n query: { limit: query.limit, cursor: query.cursor },\n });\n },\n },\n\n stats: {\n async heatmap(query: HeatmapQuery) {\n return request(\"GET\", \"/v1/stats/heatmap\", HeatmapResponseSchema, {\n query: { year: query.year },\n });\n },\n async retention() {\n return request(\"GET\", \"/v1/stats/retention\", RetentionResponseSchema);\n },\n async daily(query: DailyCountQuery) {\n return request(\"GET\", \"/v1/stats/daily\", DailyCountResponseSchema, {\n query: { from: query.from, to: query.to },\n });\n },\n },\n };\n}\n\nexport type HibiClient = ReturnType<typeof createHibiClient>;\n"]}
1
+ {"version":3,"sources":["../src/_vendored/hibi-types/common.ts","../src/_vendored/hibi-types/account.ts","../src/_vendored/hibi-types/ai.ts","../src/_vendored/hibi-types/cards.ts","../src/_vendored/hibi-types/reviews.ts","../src/_vendored/hibi-types/sessions.ts","../src/_vendored/hibi-types/stats.ts","../src/_vendored/hibi-types/word-status.ts","../src/client.ts"],"names":["z"],"mappings":"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","file":"index.cjs","sourcesContent":["import { z } from \"zod\";\n\nexport const UUIDSchema = z.uuid();\n\nexport const TimestampSchema = z.iso.datetime({ offset: true });\n\nexport const PaginationQuerySchema = z.object({\n limit: z.coerce.number().int().min(1).max(200).default(50),\n cursor: z.string().optional(),\n});\n\nexport type PaginationQuery = z.infer<typeof PaginationQuerySchema>;\n\nexport const PaginatedSchema = <T extends z.ZodTypeAny>(item: T) =>\n z.object({\n items: z.array(item),\n nextCursor: z.string().nullable(),\n });\n\nexport const ErrorResponseSchema = z.object({\n error: z.object({\n code: z.string(),\n message: z.string(),\n details: z.unknown().optional(),\n }),\n});\n\nexport type ErrorResponse = z.infer<typeof ErrorResponseSchema>;\n","import { z } from \"zod\";\nimport { TimestampSchema, UUIDSchema } from \"./common.ts\";\n\nexport const AccountSchema = z.object({\n id: UUIDSchema,\n email: z.email(),\n createdAt: TimestampSchema,\n});\nexport type Account = z.infer<typeof AccountSchema>;\n\nexport const ApiKeySchema = z.object({\n id: UUIDSchema,\n name: z.string().min(1).max(80),\n lastUsedAt: TimestampSchema.nullable(),\n createdAt: TimestampSchema,\n revokedAt: TimestampSchema.nullable(),\n});\nexport type ApiKey = z.infer<typeof ApiKeySchema>;\n\nexport const CreateApiKeyInputSchema = z.object({\n name: z.string().min(1).max(80),\n});\nexport type CreateApiKeyInput = z.infer<typeof CreateApiKeyInputSchema>;\n\nexport const CreateApiKeyResponseSchema = z.object({\n apiKey: ApiKeySchema,\n rawKey: z.string(),\n});\nexport type CreateApiKeyResponse = z.infer<typeof CreateApiKeyResponseSchema>;\n\nexport const SaveOpenRouterKeyInputSchema = z.object({\n apiKey: z.string().min(1).max(512),\n});\nexport type SaveOpenRouterKeyInput = z.infer<typeof SaveOpenRouterKeyInputSchema>;\n\n// Returned by PUT /v1/account/openrouter-key after a successful probe.\n// Mirrors the fields OpenRouter's GET /auth/key exposes.\nexport const OpenRouterKeyInfoSchema = z.object({\n label: z.string(),\n usage: z.number().nullable(),\n limit: z.number().nullable(),\n});\nexport type OpenRouterKeyInfo = z.infer<typeof OpenRouterKeyInfoSchema>;\n\nexport const OpenRouterKeyStatusSchema = z.object({\n configured: z.boolean(),\n keyLabel: z.string().nullable().optional(),\n updatedAt: TimestampSchema.nullable().optional(),\n});\nexport type OpenRouterKeyStatus = z.infer<typeof OpenRouterKeyStatusSchema>;\n","import { z } from \"zod\";\n\n// Returned by GET /v1/ai/key (client API-key authed). The discovery\n// endpoint for AI features: lets a client decide whether to surface\n// the \"configure OpenRouter in portal\" prompt before invoking proxy\n// routes.\nexport const ClientAiStatusSchema = z.discriminatedUnion(\"configured\", [\n z.object({\n configured: z.literal(true),\n label: z.string(),\n usage: z.number().nullable(),\n limit: z.number().nullable(),\n }),\n z.object({\n configured: z.literal(false),\n }),\n]);\nexport type ClientAiStatus = z.infer<typeof ClientAiStatusSchema>;\n","import { z } from \"zod\";\nimport { TimestampSchema, UUIDSchema } from \"./common.ts\";\n\nexport const FuriganaPairSchema = z.object({\n base: z.string(),\n reading: z.string(),\n});\nexport type FuriganaPair = z.infer<typeof FuriganaPairSchema>;\n\nexport const KanjiEntrySchema = z.object({\n kanji: z.string().length(1),\n meaning: z.string(),\n wanikaniLevel: z.number().int().min(1).max(60).nullable(),\n});\nexport type KanjiEntry = z.infer<typeof KanjiEntrySchema>;\n\nexport const CardSchema = z.object({\n id: UUIDSchema,\n userId: UUIDSchema,\n createdAt: TimestampSchema,\n updatedAt: TimestampSchema,\n\n sentence: z.string().min(1),\n focusWord: z.string().min(1),\n focusWordReading: z.string().min(1),\n furigana: z.array(FuriganaPairSchema),\n english: z.string(),\n glosses: z.array(z.string()),\n grammarNote: z.string().nullable(),\n kanjiList: z.array(KanjiEntrySchema),\n\n imageKey: z.string().nullable(),\n audioKey: z.string().nullable(),\n imageUrl: z.string().url().nullable(),\n audioUrl: z.string().url().nullable(),\n\n source: z.string(),\n tags: z.array(z.string()),\n});\nexport type Card = z.infer<typeof CardSchema>;\n\nexport const CreateCardInputSchema = CardSchema.omit({\n id: true,\n userId: true,\n createdAt: true,\n updatedAt: true,\n imageUrl: true,\n audioUrl: true,\n});\nexport type CreateCardInput = z.infer<typeof CreateCardInputSchema>;\n\nexport const UpdateCardInputSchema = CreateCardInputSchema.partial();\nexport type UpdateCardInput = z.infer<typeof UpdateCardInputSchema>;\n\nexport const ListCardsSortSchema = z.enum([\"newest\", \"oldest\", \"due-soonest\"]);\nexport type ListCardsSort = z.infer<typeof ListCardsSortSchema>;\n\nexport const ListCardsQuerySchema = z.object({\n limit: z.coerce.number().int().min(1).max(200).default(50),\n cursor: z.string().optional(),\n tag: z.string().optional(),\n source: z.string().optional(),\n q: z.string().min(1).max(200).optional(),\n sort: ListCardsSortSchema.default(\"newest\"),\n});\nexport type ListCardsQuery = z.infer<typeof ListCardsQuerySchema>;\n","import { z } from \"zod\";\nimport { TimestampSchema, UUIDSchema } from \"./common.ts\";\n\nexport const CardStateSchema = z.enum([\"new\", \"learning\", \"review\", \"relearning\"]);\nexport type CardStateValue = z.infer<typeof CardStateSchema>;\n\nexport const ReviewRatingSchema = z.union([z.literal(1), z.literal(2), z.literal(3), z.literal(4)]);\nexport type ReviewRating = z.infer<typeof ReviewRatingSchema>;\n\nexport const ReviewSchema = z.object({\n id: UUIDSchema,\n userId: UUIDSchema,\n cardId: UUIDSchema,\n rating: ReviewRatingSchema,\n reviewedAt: TimestampSchema,\n elapsedDays: z.number(),\n scheduledDays: z.number(),\n stateBefore: CardStateSchema,\n stateAfter: CardStateSchema,\n});\nexport type Review = z.infer<typeof ReviewSchema>;\n\nexport const CardStateRowSchema = z.object({\n cardId: UUIDSchema,\n userId: UUIDSchema,\n due: TimestampSchema,\n stability: z.number(),\n difficulty: z.number(),\n elapsedDays: z.number(),\n scheduledDays: z.number(),\n reps: z.number().int().nonnegative(),\n lapses: z.number().int().nonnegative(),\n learningSteps: z.number().int().nonnegative(),\n state: CardStateSchema,\n lastReview: TimestampSchema.nullable(),\n});\nexport type CardStateRow = z.infer<typeof CardStateRowSchema>;\n\nexport const DueReviewsQuerySchema = z.object({\n limit: z.coerce.number().int().min(1).max(200).default(50),\n before: TimestampSchema.optional(),\n});\nexport type DueReviewsQuery = z.infer<typeof DueReviewsQuerySchema>;\n\nexport const SubmitReviewInputSchema = z.object({\n cardId: UUIDSchema,\n rating: ReviewRatingSchema,\n reviewedAt: TimestampSchema.optional(),\n});\nexport type SubmitReviewInput = z.infer<typeof SubmitReviewInputSchema>;\n\nexport const SubmitReviewResultSchema = z.object({\n review: ReviewSchema,\n cardState: CardStateRowSchema,\n});\nexport type SubmitReviewResult = z.infer<typeof SubmitReviewResultSchema>;\n","import { z } from \"zod\";\nimport { TimestampSchema, UUIDSchema } from \"./common.ts\";\n\n// Free-form per-app context (e.g. { trackId } for Hibi Koe). Keep as\n// a record so future apps can attach their own keys without a type bump.\nexport const SessionMetadataSchema = z.record(z.string(), z.unknown()).nullable();\n\nexport const SessionSchema = z.object({\n id: UUIDSchema,\n userId: UUIDSchema,\n kind: z.string().min(1),\n source: z.string().min(1),\n startedAt: TimestampSchema,\n endedAt: TimestampSchema,\n durationMs: z.number().int().nonnegative(),\n metadata: SessionMetadataSchema,\n createdAt: TimestampSchema,\n});\nexport type Session = z.infer<typeof SessionSchema>;\n\nexport const CreateSessionInputSchema = SessionSchema.omit({\n id: true,\n userId: true,\n createdAt: true,\n}).extend({\n metadata: SessionMetadataSchema.optional(),\n});\nexport type CreateSessionInput = z.infer<typeof CreateSessionInputSchema>;\n\nexport const ListSessionsQuerySchema = z.object({\n limit: z.coerce.number().int().min(1).max(200).default(50),\n cursor: z.string().optional(),\n kind: z.string().optional(),\n source: z.string().optional(),\n // Inclusive lower bound, exclusive upper. Both ISO-8601 timestamps.\n from: z.iso.datetime({ offset: true }).optional(),\n to: z.iso.datetime({ offset: true }).optional(),\n});\nexport type ListSessionsQuery = z.infer<typeof ListSessionsQuerySchema>;\n","import { z } from \"zod\";\nimport { TimestampSchema } from \"./common.ts\";\n\nexport const HeatmapDaySchema = z.object({\n date: z.iso.date(),\n count: z.number().int().nonnegative(),\n});\nexport type HeatmapDay = z.infer<typeof HeatmapDaySchema>;\n\nexport const HeatmapQuerySchema = z.object({\n year: z.coerce.number().int().min(2000).max(2100),\n});\nexport type HeatmapQuery = z.infer<typeof HeatmapQuerySchema>;\n\nexport const HeatmapResponseSchema = z.object({\n year: z.number().int(),\n days: z.array(HeatmapDaySchema),\n});\nexport type HeatmapResponse = z.infer<typeof HeatmapResponseSchema>;\n\nexport const RetentionPointSchema = z.object({\n intervalDays: z.number().int().nonnegative(),\n retention: z.number().min(0).max(1),\n sampleSize: z.number().int().nonnegative(),\n});\nexport type RetentionPoint = z.infer<typeof RetentionPointSchema>;\n\nexport const RetentionResponseSchema = z.object({\n generatedAt: TimestampSchema,\n points: z.array(RetentionPointSchema),\n});\nexport type RetentionResponse = z.infer<typeof RetentionResponseSchema>;\n\nexport const DailyCountQuerySchema = z.object({\n from: z.iso.date(),\n to: z.iso.date(),\n});\nexport type DailyCountQuery = z.infer<typeof DailyCountQuerySchema>;\n\nexport const DailyCountSchema = z.object({\n date: z.iso.date(),\n reviews: z.number().int().nonnegative(),\n again: z.number().int().nonnegative(),\n hard: z.number().int().nonnegative(),\n good: z.number().int().nonnegative(),\n easy: z.number().int().nonnegative(),\n});\nexport type DailyCount = z.infer<typeof DailyCountSchema>;\n\nexport const DailyCountResponseSchema = z.object({\n days: z.array(DailyCountSchema),\n});\nexport type DailyCountResponse = z.infer<typeof DailyCountResponseSchema>;\n","import { z } from \"zod\";\nimport { TimestampSchema, UUIDSchema } from \"./common.ts\";\n\n// Three writeable values. 'unknown' is the implicit default and is\n// represented by the absence of a row, never stored explicitly.\nexport const WordStatusSchema = z.enum([\"learning\", \"known\", \"ignored\"]);\nexport type WordStatus = z.infer<typeof WordStatusSchema>;\n\n// Manual word-status row as the user set it. (lemma, reading) is unique\n// per-user; updating with the same key overwrites status + updatedAt.\nexport const ManualWordStatusSchema = z.object({\n id: UUIDSchema,\n lemma: z.string().min(1),\n reading: z.string().min(1),\n status: WordStatusSchema,\n createdAt: TimestampSchema,\n updatedAt: TimestampSchema,\n});\nexport type ManualWordStatus = z.infer<typeof ManualWordStatusSchema>;\n\n// PUT /v1/word-status body. status: null deletes the row.\nexport const SetWordStatusInputSchema = z.object({\n lemma: z.string().min(1),\n reading: z.string().min(1),\n status: WordStatusSchema.nullable(),\n});\nexport type SetWordStatusInput = z.infer<typeof SetWordStatusInputSchema>;\n\n// One row in the merged /v1/known-words response. source distinguishes\n// manual marks from SRS-derived classifications. When source is 'srs',\n// cardId + intervalDays are populated; clients should treat the status\n// as read-only and tell users to adjust by reviewing the card.\nexport const KnownWordSchema = z.object({\n lemma: z.string(),\n reading: z.string(),\n status: WordStatusSchema,\n source: z.enum([\"manual\", \"srs\"]),\n cardId: UUIDSchema.nullable(),\n intervalDays: z.number().int().nullable(),\n updatedAt: TimestampSchema,\n});\nexport type KnownWord = z.infer<typeof KnownWordSchema>;\n","import { z } from \"zod\";\nimport {\n CardSchema,\n ClientAiStatusSchema,\n type CreateCardInput,\n CreateCardInputSchema,\n type DailyCountQuery,\n DailyCountResponseSchema,\n type HeatmapQuery,\n HeatmapResponseSchema,\n KnownWordSchema,\n type ListCardsQuery,\n ManualWordStatusSchema,\n PaginatedSchema,\n type PaginationQuery,\n RetentionResponseSchema,\n CreateSessionInputSchema,\n type CreateSessionInput,\n type SetWordStatusInput,\n SetWordStatusInputSchema,\n ListSessionsQuerySchema,\n type ListSessionsQuery,\n SessionSchema,\n type SubmitReviewInput,\n SubmitReviewInputSchema,\n SubmitReviewResultSchema,\n type UpdateCardInput,\n UpdateCardInputSchema,\n} from \"./_vendored/hibi-types/index.ts\";\n\nexport interface HibiClientConfig {\n apiKey: string;\n baseUrl: string;\n fetch?: typeof fetch;\n}\n\nexport interface HibiClientError extends Error {\n status: number;\n body: unknown;\n}\n\nconst PaginatedCardSchema = PaginatedSchema(CardSchema);\nconst PaginatedSessionSchema = PaginatedSchema(SessionSchema);\nconst PaginatedManualStatusSchema = PaginatedSchema(ManualWordStatusSchema);\nconst PaginatedKnownWordSchema = PaginatedSchema(KnownWordSchema);\nconst NullableManualStatusSchema = ManualWordStatusSchema.nullable();\nconst DueResponseSchema = z.object({\n items: z.array(\n z.object({ card: CardSchema, cardState: SubmitReviewResultSchema.shape.cardState }),\n ),\n});\nconst UploadResponseSchema = z.object({ key: z.string() });\n\n// React-Native-style file reference. RN's FormData.append accepts this\n// shape directly; we type it explicitly so consumers can build it\n// without depending on RN-specific globals.\nexport type RNFileRef = { uri: string; name: string; type: string };\n\n// What client.uploads.* accepts. On web pass a Blob/File; on RN pass an\n// RNFileRef. In both cases the SDK builds the multipart body.\nexport type UploadInput = Blob | RNFileRef;\nexport type AudioUploadInput = UploadInput;\n\nfunction asError(status: number, body: unknown, message?: string): HibiClientError {\n const err = new Error(message ?? `Hibi API error: ${status}`) as HibiClientError;\n err.status = status;\n err.body = body;\n return err;\n}\n\nfunction isFormData(value: unknown): value is FormData {\n return typeof FormData !== \"undefined\" && value instanceof FormData;\n}\n\nexport function createHibiClient(config: HibiClientConfig) {\n const fetchImpl = config.fetch ?? fetch;\n const base = config.baseUrl.replace(/\\/+$/, \"\");\n\n async function request<T>(\n method: string,\n path: string,\n schema: z.ZodType<T>,\n init: {\n body?: unknown;\n query?: Record<string, string | number | undefined>;\n } = {},\n ): Promise<T> {\n const url = new URL(`${base}${path}`);\n if (init.query) {\n for (const [k, v] of Object.entries(init.query)) {\n if (v !== undefined) url.searchParams.set(k, String(v));\n }\n }\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${config.apiKey}`,\n };\n const requestInit: RequestInit = { method, headers };\n if (init.body !== undefined) {\n if (isFormData(init.body)) {\n // Don't set Content-Type for multipart — the runtime appends\n // the correct boundary. RN in particular breaks if we set it.\n requestInit.body = init.body;\n } else {\n headers[\"Content-Type\"] = \"application/json\";\n requestInit.body = JSON.stringify(init.body);\n }\n }\n\n const res = await fetchImpl(url.toString(), requestInit);\n\n if (res.status === 204) return undefined as T;\n\n const text = await res.text();\n const contentType = res.headers.get(\"content-type\") ?? \"\";\n let body: unknown = null;\n if (text) {\n if (contentType.includes(\"application/json\")) {\n try {\n body = JSON.parse(text);\n } catch (err) {\n throw asError(\n res.status,\n { rawText: text.slice(0, 500), parseError: String(err) },\n `Hibi API ${res.status}: malformed JSON from ${url.toString()} (first 200 chars: ${text.slice(0, 200)})`,\n );\n }\n } else {\n // Non-JSON response — almost always means we hit a misrouted host\n // (Vercel 404 wall, gateway HTML, captive portal). Surface the\n // first chunk of the body so the caller knows where to look.\n throw asError(\n res.status,\n { rawText: text.slice(0, 500), contentType },\n `Hibi API ${res.status}: expected JSON from ${url.toString()} but got ${contentType || \"unknown content-type\"} (first 200 chars: ${text.slice(0, 200)})`,\n );\n }\n }\n\n if (!res.ok) throw asError(res.status, body);\n return schema.parse(body);\n }\n\n // Like request() but returns the raw Response without parsing. Used by\n // /v1/ai/* proxy routes where the response body might be SSE, binary\n // audio, or OR-shaped JSON we deliberately don't validate.\n async function requestRaw(\n method: string,\n path: string,\n init: { body?: unknown; query?: Record<string, string | number | undefined> } = {},\n ): Promise<Response> {\n const url = new URL(`${base}${path}`);\n if (init.query) {\n for (const [k, v] of Object.entries(init.query)) {\n if (v !== undefined) url.searchParams.set(k, String(v));\n }\n }\n const headers: Record<string, string> = {\n Authorization: `Bearer ${config.apiKey}`,\n };\n const requestInit: RequestInit = { method, headers };\n if (init.body !== undefined) {\n headers[\"Content-Type\"] = \"application/json\";\n requestInit.body = JSON.stringify(init.body);\n }\n const res = await fetchImpl(url.toString(), requestInit);\n if (!res.ok) {\n const text = await res.text();\n let body: unknown = text;\n try {\n body = JSON.parse(text);\n } catch {\n // keep as text\n }\n throw asError(res.status, body);\n }\n return res;\n }\n\n function buildUploadForm(input: UploadInput, defaultName: string): FormData {\n const fd = new FormData();\n if (typeof Blob !== \"undefined\" && input instanceof Blob) {\n // Blob/File on web/node20+. Pass a name so the server sees a filename.\n const name = \"name\" in input && typeof input.name === \"string\" ? input.name : defaultName;\n fd.append(\"file\", input, name);\n } else {\n // RN file ref. The cast is unavoidable: RN's FormData accepts this\n // shape but the lib.dom.d.ts FormData type doesn't model it.\n fd.append(\"file\", input as unknown as Blob);\n }\n return fd;\n }\n\n return {\n cards: {\n async create(input: CreateCardInput) {\n const validated = CreateCardInputSchema.parse(input);\n return request(\"POST\", \"/v1/cards\", CardSchema, { body: validated });\n },\n async list(query: ListCardsQuery = { limit: 50, sort: \"newest\" }) {\n return request(\"GET\", \"/v1/cards\", PaginatedCardSchema, {\n query: {\n limit: query.limit,\n cursor: query.cursor,\n tag: query.tag,\n source: query.source,\n q: query.q,\n sort: query.sort,\n },\n });\n },\n async get(id: string) {\n return request(\"GET\", `/v1/cards/${id}`, CardSchema);\n },\n async update(id: string, input: UpdateCardInput) {\n const validated = UpdateCardInputSchema.parse(input);\n return request(\"PATCH\", `/v1/cards/${id}`, CardSchema, { body: validated });\n },\n async remove(id: string): Promise<void> {\n await request(\"DELETE\", `/v1/cards/${id}`, z.unknown());\n },\n },\n\n uploads: {\n async audio(input: UploadInput) {\n return request(\"POST\", \"/v1/uploads/audio\", UploadResponseSchema, {\n body: buildUploadForm(input, \"clip.m4a\"),\n });\n },\n async image(input: UploadInput) {\n return request(\"POST\", \"/v1/uploads/image\", UploadResponseSchema, {\n body: buildUploadForm(input, \"image.jpg\"),\n });\n },\n },\n\n sessions: {\n async create(input: CreateSessionInput) {\n const validated = CreateSessionInputSchema.parse(input);\n return request(\"POST\", \"/v1/sessions\", SessionSchema, { body: validated });\n },\n async list(query: ListSessionsQuery = { limit: 50 }) {\n const validated = ListSessionsQuerySchema.parse(query);\n return request(\"GET\", \"/v1/sessions\", PaginatedSessionSchema, {\n query: {\n limit: validated.limit,\n cursor: validated.cursor,\n kind: validated.kind,\n source: validated.source,\n from: validated.from,\n to: validated.to,\n },\n });\n },\n },\n\n reviews: {\n async due(query: { limit?: number; before?: string } = {}) {\n return request(\"GET\", \"/v1/reviews/due\", DueResponseSchema, {\n query: { limit: query.limit, before: query.before },\n });\n },\n async submit(input: SubmitReviewInput) {\n const validated = SubmitReviewInputSchema.parse(input);\n return request(\"POST\", \"/v1/reviews\", SubmitReviewResultSchema, { body: validated });\n },\n },\n\n wordStatus: {\n // Upsert (lemma, reading) for the caller; pass status: null to delete.\n async set(input: SetWordStatusInput) {\n const validated = SetWordStatusInputSchema.parse(input);\n return request(\"PUT\", \"/v1/word-status\", NullableManualStatusSchema, {\n body: validated,\n });\n },\n // Paginated list of just the manual rows (no SRS rows).\n async list(query: PaginationQuery = { limit: 50 }) {\n return request(\"GET\", \"/v1/word-status\", PaginatedManualStatusSchema, {\n query: { limit: query.limit, cursor: query.cursor },\n });\n },\n },\n\n knownWords: {\n // Merged manual + SRS classifications. Single source of truth for\n // the underline-by-status view in reading clients.\n async list(query: PaginationQuery = { limit: 50 }) {\n return request(\"GET\", \"/v1/known-words\", PaginatedKnownWordSchema, {\n query: { limit: query.limit, cursor: query.cursor },\n });\n },\n },\n\n stats: {\n async heatmap(query: HeatmapQuery) {\n return request(\"GET\", \"/v1/stats/heatmap\", HeatmapResponseSchema, {\n query: { year: query.year },\n });\n },\n async retention() {\n return request(\"GET\", \"/v1/stats/retention\", RetentionResponseSchema);\n },\n async daily(query: DailyCountQuery) {\n return request(\"GET\", \"/v1/stats/daily\", DailyCountResponseSchema, {\n query: { from: query.from, to: query.to },\n });\n },\n },\n\n ai: {\n // Discovery: is the user's OpenRouter key configured server-side?\n // Hit this on app start before surfacing AI-dependent UI.\n async key() {\n return request(\"GET\", \"/v1/ai/key\", ClientAiStatusSchema);\n },\n // OpenRouter chat completions, proxied. Returns the raw Response\n // so the caller can stream from res.body (when stream:true) or\n // call res.json() (when stream:false).\n async chatCompletions(body: Record<string, unknown>) {\n return requestRaw(\"POST\", \"/v1/ai/chat/completions\", { body });\n },\n audio: {\n async transcriptions(body: Record<string, unknown>): Promise<unknown> {\n const res = await requestRaw(\"POST\", \"/v1/ai/audio/transcriptions\", { body });\n return res.json();\n },\n // Returns the raw audio bytes (MP3 by default).\n async speech(body: Record<string, unknown>): Promise<Uint8Array> {\n const res = await requestRaw(\"POST\", \"/v1/ai/audio/speech\", { body });\n return new Uint8Array(await res.arrayBuffer());\n },\n },\n },\n };\n}\n\nexport type HibiClient = ReturnType<typeof createHibiClient>;\n"]}
package/dist/index.d.cts CHANGED
@@ -33,6 +33,8 @@ declare const CardSchema: z.ZodObject<{
33
33
  }, z.core.$strip>>;
34
34
  imageKey: z.ZodNullable<z.ZodString>;
35
35
  audioKey: z.ZodNullable<z.ZodString>;
36
+ imageUrl: z.ZodNullable<z.ZodString>;
37
+ audioUrl: z.ZodNullable<z.ZodString>;
36
38
  source: z.ZodString;
37
39
  tags: z.ZodArray<z.ZodString>;
38
40
  }, z.core.$strip>;
@@ -81,11 +83,23 @@ declare const UpdateCardInputSchema: z.ZodObject<{
81
83
  tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
82
84
  }, z.core.$strip>;
83
85
  type UpdateCardInput = z.infer<typeof UpdateCardInputSchema>;
86
+ declare const ListCardsSortSchema: z.ZodEnum<{
87
+ newest: "newest";
88
+ oldest: "oldest";
89
+ "due-soonest": "due-soonest";
90
+ }>;
91
+ type ListCardsSort = z.infer<typeof ListCardsSortSchema>;
84
92
  declare const ListCardsQuerySchema: z.ZodObject<{
85
93
  limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
86
94
  cursor: z.ZodOptional<z.ZodString>;
87
95
  tag: z.ZodOptional<z.ZodString>;
88
96
  source: z.ZodOptional<z.ZodString>;
97
+ q: z.ZodOptional<z.ZodString>;
98
+ sort: z.ZodDefault<z.ZodEnum<{
99
+ newest: "newest";
100
+ oldest: "oldest";
101
+ "due-soonest": "due-soonest";
102
+ }>>;
89
103
  }, z.core.$strip>;
90
104
  type ListCardsQuery = z.infer<typeof ListCardsQuerySchema>;
91
105
 
@@ -324,6 +338,8 @@ declare function createHibiClient(config: HibiClientConfig): {
324
338
  }[];
325
339
  imageKey: string | null;
326
340
  audioKey: string | null;
341
+ imageUrl: string | null;
342
+ audioUrl: string | null;
327
343
  source: string;
328
344
  tags: string[];
329
345
  }>;
@@ -350,6 +366,8 @@ declare function createHibiClient(config: HibiClientConfig): {
350
366
  }[];
351
367
  imageKey: string | null;
352
368
  audioKey: string | null;
369
+ imageUrl: string | null;
370
+ audioUrl: string | null;
353
371
  source: string;
354
372
  tags: string[];
355
373
  }[];
@@ -377,6 +395,8 @@ declare function createHibiClient(config: HibiClientConfig): {
377
395
  }[];
378
396
  imageKey: string | null;
379
397
  audioKey: string | null;
398
+ imageUrl: string | null;
399
+ audioUrl: string | null;
380
400
  source: string;
381
401
  tags: string[];
382
402
  }>;
@@ -402,6 +422,8 @@ declare function createHibiClient(config: HibiClientConfig): {
402
422
  }[];
403
423
  imageKey: string | null;
404
424
  audioKey: string | null;
425
+ imageUrl: string | null;
426
+ audioUrl: string | null;
405
427
  source: string;
406
428
  tags: string[];
407
429
  }>;
@@ -470,6 +492,8 @@ declare function createHibiClient(config: HibiClientConfig): {
470
492
  }[];
471
493
  imageKey: string | null;
472
494
  audioKey: string | null;
495
+ imageUrl: string | null;
496
+ audioUrl: string | null;
473
497
  source: string;
474
498
  tags: string[];
475
499
  };
@@ -579,7 +603,22 @@ declare function createHibiClient(config: HibiClientConfig): {
579
603
  }[];
580
604
  }>;
581
605
  };
606
+ ai: {
607
+ key(): Promise<{
608
+ configured: true;
609
+ label: string;
610
+ usage: number | null;
611
+ limit: number | null;
612
+ } | {
613
+ configured: false;
614
+ }>;
615
+ chatCompletions(body: Record<string, unknown>): Promise<Response>;
616
+ audio: {
617
+ transcriptions(body: Record<string, unknown>): Promise<unknown>;
618
+ speech(body: Record<string, unknown>): Promise<Uint8Array>;
619
+ };
620
+ };
582
621
  };
583
622
  type HibiClient = ReturnType<typeof createHibiClient>;
584
623
 
585
- export { type AudioUploadInput, type Card, type CardStateRow, type CardStateValue, type CreateCardInput, type DailyCount, type DailyCountResponse, type FuriganaPair, type HeatmapDay, type HeatmapResponse, type HibiClient, type HibiClientConfig, type HibiClientError, type KanjiEntry, type ListCardsQuery, type RNFileRef, type RetentionPoint, type RetentionResponse, type Review, type ReviewRating, type SubmitReviewInput, type SubmitReviewResult, type UpdateCardInput, createHibiClient };
624
+ export { type AudioUploadInput, type Card, type CardStateRow, type CardStateValue, type CreateCardInput, type DailyCount, type DailyCountResponse, type FuriganaPair, type HeatmapDay, type HeatmapResponse, type HibiClient, type HibiClientConfig, type HibiClientError, type KanjiEntry, type ListCardsQuery, type ListCardsSort, type RNFileRef, type RetentionPoint, type RetentionResponse, type Review, type ReviewRating, type SubmitReviewInput, type SubmitReviewResult, type UpdateCardInput, createHibiClient };
package/dist/index.d.ts CHANGED
@@ -33,6 +33,8 @@ declare const CardSchema: z.ZodObject<{
33
33
  }, z.core.$strip>>;
34
34
  imageKey: z.ZodNullable<z.ZodString>;
35
35
  audioKey: z.ZodNullable<z.ZodString>;
36
+ imageUrl: z.ZodNullable<z.ZodString>;
37
+ audioUrl: z.ZodNullable<z.ZodString>;
36
38
  source: z.ZodString;
37
39
  tags: z.ZodArray<z.ZodString>;
38
40
  }, z.core.$strip>;
@@ -81,11 +83,23 @@ declare const UpdateCardInputSchema: z.ZodObject<{
81
83
  tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
82
84
  }, z.core.$strip>;
83
85
  type UpdateCardInput = z.infer<typeof UpdateCardInputSchema>;
86
+ declare const ListCardsSortSchema: z.ZodEnum<{
87
+ newest: "newest";
88
+ oldest: "oldest";
89
+ "due-soonest": "due-soonest";
90
+ }>;
91
+ type ListCardsSort = z.infer<typeof ListCardsSortSchema>;
84
92
  declare const ListCardsQuerySchema: z.ZodObject<{
85
93
  limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
86
94
  cursor: z.ZodOptional<z.ZodString>;
87
95
  tag: z.ZodOptional<z.ZodString>;
88
96
  source: z.ZodOptional<z.ZodString>;
97
+ q: z.ZodOptional<z.ZodString>;
98
+ sort: z.ZodDefault<z.ZodEnum<{
99
+ newest: "newest";
100
+ oldest: "oldest";
101
+ "due-soonest": "due-soonest";
102
+ }>>;
89
103
  }, z.core.$strip>;
90
104
  type ListCardsQuery = z.infer<typeof ListCardsQuerySchema>;
91
105
 
@@ -324,6 +338,8 @@ declare function createHibiClient(config: HibiClientConfig): {
324
338
  }[];
325
339
  imageKey: string | null;
326
340
  audioKey: string | null;
341
+ imageUrl: string | null;
342
+ audioUrl: string | null;
327
343
  source: string;
328
344
  tags: string[];
329
345
  }>;
@@ -350,6 +366,8 @@ declare function createHibiClient(config: HibiClientConfig): {
350
366
  }[];
351
367
  imageKey: string | null;
352
368
  audioKey: string | null;
369
+ imageUrl: string | null;
370
+ audioUrl: string | null;
353
371
  source: string;
354
372
  tags: string[];
355
373
  }[];
@@ -377,6 +395,8 @@ declare function createHibiClient(config: HibiClientConfig): {
377
395
  }[];
378
396
  imageKey: string | null;
379
397
  audioKey: string | null;
398
+ imageUrl: string | null;
399
+ audioUrl: string | null;
380
400
  source: string;
381
401
  tags: string[];
382
402
  }>;
@@ -402,6 +422,8 @@ declare function createHibiClient(config: HibiClientConfig): {
402
422
  }[];
403
423
  imageKey: string | null;
404
424
  audioKey: string | null;
425
+ imageUrl: string | null;
426
+ audioUrl: string | null;
405
427
  source: string;
406
428
  tags: string[];
407
429
  }>;
@@ -470,6 +492,8 @@ declare function createHibiClient(config: HibiClientConfig): {
470
492
  }[];
471
493
  imageKey: string | null;
472
494
  audioKey: string | null;
495
+ imageUrl: string | null;
496
+ audioUrl: string | null;
473
497
  source: string;
474
498
  tags: string[];
475
499
  };
@@ -579,7 +603,22 @@ declare function createHibiClient(config: HibiClientConfig): {
579
603
  }[];
580
604
  }>;
581
605
  };
606
+ ai: {
607
+ key(): Promise<{
608
+ configured: true;
609
+ label: string;
610
+ usage: number | null;
611
+ limit: number | null;
612
+ } | {
613
+ configured: false;
614
+ }>;
615
+ chatCompletions(body: Record<string, unknown>): Promise<Response>;
616
+ audio: {
617
+ transcriptions(body: Record<string, unknown>): Promise<unknown>;
618
+ speech(body: Record<string, unknown>): Promise<Uint8Array>;
619
+ };
620
+ };
582
621
  };
583
622
  type HibiClient = ReturnType<typeof createHibiClient>;
584
623
 
585
- export { type AudioUploadInput, type Card, type CardStateRow, type CardStateValue, type CreateCardInput, type DailyCount, type DailyCountResponse, type FuriganaPair, type HeatmapDay, type HeatmapResponse, type HibiClient, type HibiClientConfig, type HibiClientError, type KanjiEntry, type ListCardsQuery, type RNFileRef, type RetentionPoint, type RetentionResponse, type Review, type ReviewRating, type SubmitReviewInput, type SubmitReviewResult, type UpdateCardInput, createHibiClient };
624
+ export { type AudioUploadInput, type Card, type CardStateRow, type CardStateValue, type CreateCardInput, type DailyCount, type DailyCountResponse, type FuriganaPair, type HeatmapDay, type HeatmapResponse, type HibiClient, type HibiClientConfig, type HibiClientError, type KanjiEntry, type ListCardsQuery, type ListCardsSort, type RNFileRef, type RetentionPoint, type RetentionResponse, type Review, type ReviewRating, type SubmitReviewInput, type SubmitReviewResult, type UpdateCardInput, createHibiClient };
package/dist/index.js CHANGED
@@ -39,6 +39,30 @@ z.object({
39
39
  apiKey: ApiKeySchema,
40
40
  rawKey: z.string()
41
41
  });
42
+ z.object({
43
+ apiKey: z.string().min(1).max(512)
44
+ });
45
+ z.object({
46
+ label: z.string(),
47
+ usage: z.number().nullable(),
48
+ limit: z.number().nullable()
49
+ });
50
+ z.object({
51
+ configured: z.boolean(),
52
+ keyLabel: z.string().nullable().optional(),
53
+ updatedAt: TimestampSchema.nullable().optional()
54
+ });
55
+ var ClientAiStatusSchema = z.discriminatedUnion("configured", [
56
+ z.object({
57
+ configured: z.literal(true),
58
+ label: z.string(),
59
+ usage: z.number().nullable(),
60
+ limit: z.number().nullable()
61
+ }),
62
+ z.object({
63
+ configured: z.literal(false)
64
+ })
65
+ ]);
42
66
  var FuriganaPairSchema = z.object({
43
67
  base: z.string(),
44
68
  reading: z.string()
@@ -63,6 +87,8 @@ var CardSchema = z.object({
63
87
  kanjiList: z.array(KanjiEntrySchema),
64
88
  imageKey: z.string().nullable(),
65
89
  audioKey: z.string().nullable(),
90
+ imageUrl: z.string().url().nullable(),
91
+ audioUrl: z.string().url().nullable(),
66
92
  source: z.string(),
67
93
  tags: z.array(z.string())
68
94
  });
@@ -70,14 +96,19 @@ var CreateCardInputSchema = CardSchema.omit({
70
96
  id: true,
71
97
  userId: true,
72
98
  createdAt: true,
73
- updatedAt: true
99
+ updatedAt: true,
100
+ imageUrl: true,
101
+ audioUrl: true
74
102
  });
75
103
  var UpdateCardInputSchema = CreateCardInputSchema.partial();
104
+ var ListCardsSortSchema = z.enum(["newest", "oldest", "due-soonest"]);
76
105
  z.object({
77
106
  limit: z.coerce.number().int().min(1).max(200).default(50),
78
107
  cursor: z.string().optional(),
79
108
  tag: z.string().optional(),
80
- source: z.string().optional()
109
+ source: z.string().optional(),
110
+ q: z.string().min(1).max(200).optional(),
111
+ sort: ListCardsSortSchema.default("newest")
81
112
  });
82
113
  var CardStateSchema = z.enum(["new", "learning", "review", "relearning"]);
83
114
  var ReviewRatingSchema = z.union([z.literal(1), z.literal(2), z.literal(3), z.literal(4)]);
@@ -276,6 +307,33 @@ function createHibiClient(config) {
276
307
  if (!res.ok) throw asError(res.status, body);
277
308
  return schema.parse(body);
278
309
  }
310
+ async function requestRaw(method, path, init = {}) {
311
+ const url = new URL(`${base}${path}`);
312
+ if (init.query) {
313
+ for (const [k, v] of Object.entries(init.query)) {
314
+ if (v !== void 0) url.searchParams.set(k, String(v));
315
+ }
316
+ }
317
+ const headers = {
318
+ Authorization: `Bearer ${config.apiKey}`
319
+ };
320
+ const requestInit = { method, headers };
321
+ if (init.body !== void 0) {
322
+ headers["Content-Type"] = "application/json";
323
+ requestInit.body = JSON.stringify(init.body);
324
+ }
325
+ const res = await fetchImpl(url.toString(), requestInit);
326
+ if (!res.ok) {
327
+ const text = await res.text();
328
+ let body = text;
329
+ try {
330
+ body = JSON.parse(text);
331
+ } catch {
332
+ }
333
+ throw asError(res.status, body);
334
+ }
335
+ return res;
336
+ }
279
337
  function buildUploadForm(input, defaultName) {
280
338
  const fd = new FormData();
281
339
  if (typeof Blob !== "undefined" && input instanceof Blob) {
@@ -292,9 +350,16 @@ function createHibiClient(config) {
292
350
  const validated = CreateCardInputSchema.parse(input);
293
351
  return request("POST", "/v1/cards", CardSchema, { body: validated });
294
352
  },
295
- async list(query = { limit: 50 }) {
353
+ async list(query = { limit: 50, sort: "newest" }) {
296
354
  return request("GET", "/v1/cards", PaginatedCardSchema, {
297
- query: { limit: query.limit, cursor: query.cursor, tag: query.tag, source: query.source }
355
+ query: {
356
+ limit: query.limit,
357
+ cursor: query.cursor,
358
+ tag: query.tag,
359
+ source: query.source,
360
+ q: query.q,
361
+ sort: query.sort
362
+ }
298
363
  });
299
364
  },
300
365
  async get(id) {
@@ -388,6 +453,30 @@ function createHibiClient(config) {
388
453
  query: { from: query.from, to: query.to }
389
454
  });
390
455
  }
456
+ },
457
+ ai: {
458
+ // Discovery: is the user's OpenRouter key configured server-side?
459
+ // Hit this on app start before surfacing AI-dependent UI.
460
+ async key() {
461
+ return request("GET", "/v1/ai/key", ClientAiStatusSchema);
462
+ },
463
+ // OpenRouter chat completions, proxied. Returns the raw Response
464
+ // so the caller can stream from res.body (when stream:true) or
465
+ // call res.json() (when stream:false).
466
+ async chatCompletions(body) {
467
+ return requestRaw("POST", "/v1/ai/chat/completions", { body });
468
+ },
469
+ audio: {
470
+ async transcriptions(body) {
471
+ const res = await requestRaw("POST", "/v1/ai/audio/transcriptions", { body });
472
+ return res.json();
473
+ },
474
+ // Returns the raw audio bytes (MP3 by default).
475
+ async speech(body) {
476
+ const res = await requestRaw("POST", "/v1/ai/audio/speech", { body });
477
+ return new Uint8Array(await res.arrayBuffer());
478
+ }
479
+ }
391
480
  }
392
481
  };
393
482
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/_vendored/hibi-types/common.ts","../src/_vendored/hibi-types/account.ts","../src/_vendored/hibi-types/cards.ts","../src/_vendored/hibi-types/reviews.ts","../src/_vendored/hibi-types/sessions.ts","../src/_vendored/hibi-types/stats.ts","../src/_vendored/hibi-types/word-status.ts","../src/client.ts"],"names":["z"],"mappings":"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","file":"index.js","sourcesContent":["import { z } from \"zod\";\n\nexport const UUIDSchema = z.uuid();\n\nexport const TimestampSchema = z.iso.datetime({ offset: true });\n\nexport const PaginationQuerySchema = z.object({\n limit: z.coerce.number().int().min(1).max(200).default(50),\n cursor: z.string().optional(),\n});\n\nexport type PaginationQuery = z.infer<typeof PaginationQuerySchema>;\n\nexport const PaginatedSchema = <T extends z.ZodTypeAny>(item: T) =>\n z.object({\n items: z.array(item),\n nextCursor: z.string().nullable(),\n });\n\nexport const ErrorResponseSchema = z.object({\n error: z.object({\n code: z.string(),\n message: z.string(),\n details: z.unknown().optional(),\n }),\n});\n\nexport type ErrorResponse = z.infer<typeof ErrorResponseSchema>;\n","import { z } from \"zod\";\nimport { TimestampSchema, UUIDSchema } from \"./common.ts\";\n\nexport const AccountSchema = z.object({\n id: UUIDSchema,\n email: z.email(),\n createdAt: TimestampSchema,\n});\nexport type Account = z.infer<typeof AccountSchema>;\n\nexport const ApiKeySchema = z.object({\n id: UUIDSchema,\n name: z.string().min(1).max(80),\n lastUsedAt: TimestampSchema.nullable(),\n createdAt: TimestampSchema,\n revokedAt: TimestampSchema.nullable(),\n});\nexport type ApiKey = z.infer<typeof ApiKeySchema>;\n\nexport const CreateApiKeyInputSchema = z.object({\n name: z.string().min(1).max(80),\n});\nexport type CreateApiKeyInput = z.infer<typeof CreateApiKeyInputSchema>;\n\nexport const CreateApiKeyResponseSchema = z.object({\n apiKey: ApiKeySchema,\n rawKey: z.string(),\n});\nexport type CreateApiKeyResponse = z.infer<typeof CreateApiKeyResponseSchema>;\n","import { z } from \"zod\";\nimport { TimestampSchema, UUIDSchema } from \"./common.ts\";\n\nexport const FuriganaPairSchema = z.object({\n base: z.string(),\n reading: z.string(),\n});\nexport type FuriganaPair = z.infer<typeof FuriganaPairSchema>;\n\nexport const KanjiEntrySchema = z.object({\n kanji: z.string().length(1),\n meaning: z.string(),\n wanikaniLevel: z.number().int().min(1).max(60).nullable(),\n});\nexport type KanjiEntry = z.infer<typeof KanjiEntrySchema>;\n\nexport const CardSchema = z.object({\n id: UUIDSchema,\n userId: UUIDSchema,\n createdAt: TimestampSchema,\n updatedAt: TimestampSchema,\n\n sentence: z.string().min(1),\n focusWord: z.string().min(1),\n focusWordReading: z.string().min(1),\n furigana: z.array(FuriganaPairSchema),\n english: z.string(),\n glosses: z.array(z.string()),\n grammarNote: z.string().nullable(),\n kanjiList: z.array(KanjiEntrySchema),\n\n imageKey: z.string().nullable(),\n audioKey: z.string().nullable(),\n\n source: z.string(),\n tags: z.array(z.string()),\n});\nexport type Card = z.infer<typeof CardSchema>;\n\nexport const CreateCardInputSchema = CardSchema.omit({\n id: true,\n userId: true,\n createdAt: true,\n updatedAt: true,\n});\nexport type CreateCardInput = z.infer<typeof CreateCardInputSchema>;\n\nexport const UpdateCardInputSchema = CreateCardInputSchema.partial();\nexport type UpdateCardInput = z.infer<typeof UpdateCardInputSchema>;\n\nexport const ListCardsQuerySchema = z.object({\n limit: z.coerce.number().int().min(1).max(200).default(50),\n cursor: z.string().optional(),\n tag: z.string().optional(),\n source: z.string().optional(),\n});\nexport type ListCardsQuery = z.infer<typeof ListCardsQuerySchema>;\n","import { z } from \"zod\";\nimport { TimestampSchema, UUIDSchema } from \"./common.ts\";\n\nexport const CardStateSchema = z.enum([\"new\", \"learning\", \"review\", \"relearning\"]);\nexport type CardStateValue = z.infer<typeof CardStateSchema>;\n\nexport const ReviewRatingSchema = z.union([z.literal(1), z.literal(2), z.literal(3), z.literal(4)]);\nexport type ReviewRating = z.infer<typeof ReviewRatingSchema>;\n\nexport const ReviewSchema = z.object({\n id: UUIDSchema,\n userId: UUIDSchema,\n cardId: UUIDSchema,\n rating: ReviewRatingSchema,\n reviewedAt: TimestampSchema,\n elapsedDays: z.number(),\n scheduledDays: z.number(),\n stateBefore: CardStateSchema,\n stateAfter: CardStateSchema,\n});\nexport type Review = z.infer<typeof ReviewSchema>;\n\nexport const CardStateRowSchema = z.object({\n cardId: UUIDSchema,\n userId: UUIDSchema,\n due: TimestampSchema,\n stability: z.number(),\n difficulty: z.number(),\n elapsedDays: z.number(),\n scheduledDays: z.number(),\n reps: z.number().int().nonnegative(),\n lapses: z.number().int().nonnegative(),\n learningSteps: z.number().int().nonnegative(),\n state: CardStateSchema,\n lastReview: TimestampSchema.nullable(),\n});\nexport type CardStateRow = z.infer<typeof CardStateRowSchema>;\n\nexport const DueReviewsQuerySchema = z.object({\n limit: z.coerce.number().int().min(1).max(200).default(50),\n before: TimestampSchema.optional(),\n});\nexport type DueReviewsQuery = z.infer<typeof DueReviewsQuerySchema>;\n\nexport const SubmitReviewInputSchema = z.object({\n cardId: UUIDSchema,\n rating: ReviewRatingSchema,\n reviewedAt: TimestampSchema.optional(),\n});\nexport type SubmitReviewInput = z.infer<typeof SubmitReviewInputSchema>;\n\nexport const SubmitReviewResultSchema = z.object({\n review: ReviewSchema,\n cardState: CardStateRowSchema,\n});\nexport type SubmitReviewResult = z.infer<typeof SubmitReviewResultSchema>;\n","import { z } from \"zod\";\nimport { TimestampSchema, UUIDSchema } from \"./common.ts\";\n\n// Free-form per-app context (e.g. { trackId } for Hibi Koe). Keep as\n// a record so future apps can attach their own keys without a type bump.\nexport const SessionMetadataSchema = z.record(z.string(), z.unknown()).nullable();\n\nexport const SessionSchema = z.object({\n id: UUIDSchema,\n userId: UUIDSchema,\n kind: z.string().min(1),\n source: z.string().min(1),\n startedAt: TimestampSchema,\n endedAt: TimestampSchema,\n durationMs: z.number().int().nonnegative(),\n metadata: SessionMetadataSchema,\n createdAt: TimestampSchema,\n});\nexport type Session = z.infer<typeof SessionSchema>;\n\nexport const CreateSessionInputSchema = SessionSchema.omit({\n id: true,\n userId: true,\n createdAt: true,\n}).extend({\n metadata: SessionMetadataSchema.optional(),\n});\nexport type CreateSessionInput = z.infer<typeof CreateSessionInputSchema>;\n\nexport const ListSessionsQuerySchema = z.object({\n limit: z.coerce.number().int().min(1).max(200).default(50),\n cursor: z.string().optional(),\n kind: z.string().optional(),\n source: z.string().optional(),\n // Inclusive lower bound, exclusive upper. Both ISO-8601 timestamps.\n from: z.iso.datetime({ offset: true }).optional(),\n to: z.iso.datetime({ offset: true }).optional(),\n});\nexport type ListSessionsQuery = z.infer<typeof ListSessionsQuerySchema>;\n","import { z } from \"zod\";\nimport { TimestampSchema } from \"./common.ts\";\n\nexport const HeatmapDaySchema = z.object({\n date: z.iso.date(),\n count: z.number().int().nonnegative(),\n});\nexport type HeatmapDay = z.infer<typeof HeatmapDaySchema>;\n\nexport const HeatmapQuerySchema = z.object({\n year: z.coerce.number().int().min(2000).max(2100),\n});\nexport type HeatmapQuery = z.infer<typeof HeatmapQuerySchema>;\n\nexport const HeatmapResponseSchema = z.object({\n year: z.number().int(),\n days: z.array(HeatmapDaySchema),\n});\nexport type HeatmapResponse = z.infer<typeof HeatmapResponseSchema>;\n\nexport const RetentionPointSchema = z.object({\n intervalDays: z.number().int().nonnegative(),\n retention: z.number().min(0).max(1),\n sampleSize: z.number().int().nonnegative(),\n});\nexport type RetentionPoint = z.infer<typeof RetentionPointSchema>;\n\nexport const RetentionResponseSchema = z.object({\n generatedAt: TimestampSchema,\n points: z.array(RetentionPointSchema),\n});\nexport type RetentionResponse = z.infer<typeof RetentionResponseSchema>;\n\nexport const DailyCountQuerySchema = z.object({\n from: z.iso.date(),\n to: z.iso.date(),\n});\nexport type DailyCountQuery = z.infer<typeof DailyCountQuerySchema>;\n\nexport const DailyCountSchema = z.object({\n date: z.iso.date(),\n reviews: z.number().int().nonnegative(),\n again: z.number().int().nonnegative(),\n hard: z.number().int().nonnegative(),\n good: z.number().int().nonnegative(),\n easy: z.number().int().nonnegative(),\n});\nexport type DailyCount = z.infer<typeof DailyCountSchema>;\n\nexport const DailyCountResponseSchema = z.object({\n days: z.array(DailyCountSchema),\n});\nexport type DailyCountResponse = z.infer<typeof DailyCountResponseSchema>;\n","import { z } from \"zod\";\nimport { TimestampSchema, UUIDSchema } from \"./common.ts\";\n\n// Three writeable values. 'unknown' is the implicit default and is\n// represented by the absence of a row, never stored explicitly.\nexport const WordStatusSchema = z.enum([\"learning\", \"known\", \"ignored\"]);\nexport type WordStatus = z.infer<typeof WordStatusSchema>;\n\n// Manual word-status row as the user set it. (lemma, reading) is unique\n// per-user; updating with the same key overwrites status + updatedAt.\nexport const ManualWordStatusSchema = z.object({\n id: UUIDSchema,\n lemma: z.string().min(1),\n reading: z.string().min(1),\n status: WordStatusSchema,\n createdAt: TimestampSchema,\n updatedAt: TimestampSchema,\n});\nexport type ManualWordStatus = z.infer<typeof ManualWordStatusSchema>;\n\n// PUT /v1/word-status body. status: null deletes the row.\nexport const SetWordStatusInputSchema = z.object({\n lemma: z.string().min(1),\n reading: z.string().min(1),\n status: WordStatusSchema.nullable(),\n});\nexport type SetWordStatusInput = z.infer<typeof SetWordStatusInputSchema>;\n\n// One row in the merged /v1/known-words response. source distinguishes\n// manual marks from SRS-derived classifications. When source is 'srs',\n// cardId + intervalDays are populated; clients should treat the status\n// as read-only and tell users to adjust by reviewing the card.\nexport const KnownWordSchema = z.object({\n lemma: z.string(),\n reading: z.string(),\n status: WordStatusSchema,\n source: z.enum([\"manual\", \"srs\"]),\n cardId: UUIDSchema.nullable(),\n intervalDays: z.number().int().nullable(),\n updatedAt: TimestampSchema,\n});\nexport type KnownWord = z.infer<typeof KnownWordSchema>;\n","import { z } from \"zod\";\nimport {\n CardSchema,\n type CreateCardInput,\n CreateCardInputSchema,\n type DailyCountQuery,\n DailyCountResponseSchema,\n type HeatmapQuery,\n HeatmapResponseSchema,\n KnownWordSchema,\n type ListCardsQuery,\n ManualWordStatusSchema,\n PaginatedSchema,\n type PaginationQuery,\n RetentionResponseSchema,\n CreateSessionInputSchema,\n type CreateSessionInput,\n type SetWordStatusInput,\n SetWordStatusInputSchema,\n ListSessionsQuerySchema,\n type ListSessionsQuery,\n SessionSchema,\n type SubmitReviewInput,\n SubmitReviewInputSchema,\n SubmitReviewResultSchema,\n type UpdateCardInput,\n UpdateCardInputSchema,\n} from \"./_vendored/hibi-types/index.ts\";\n\nexport interface HibiClientConfig {\n apiKey: string;\n baseUrl: string;\n fetch?: typeof fetch;\n}\n\nexport interface HibiClientError extends Error {\n status: number;\n body: unknown;\n}\n\nconst PaginatedCardSchema = PaginatedSchema(CardSchema);\nconst PaginatedSessionSchema = PaginatedSchema(SessionSchema);\nconst PaginatedManualStatusSchema = PaginatedSchema(ManualWordStatusSchema);\nconst PaginatedKnownWordSchema = PaginatedSchema(KnownWordSchema);\nconst NullableManualStatusSchema = ManualWordStatusSchema.nullable();\nconst DueResponseSchema = z.object({\n items: z.array(\n z.object({ card: CardSchema, cardState: SubmitReviewResultSchema.shape.cardState }),\n ),\n});\nconst UploadResponseSchema = z.object({ key: z.string() });\n\n// React-Native-style file reference. RN's FormData.append accepts this\n// shape directly; we type it explicitly so consumers can build it\n// without depending on RN-specific globals.\nexport type RNFileRef = { uri: string; name: string; type: string };\n\n// What client.uploads.* accepts. On web pass a Blob/File; on RN pass an\n// RNFileRef. In both cases the SDK builds the multipart body.\nexport type UploadInput = Blob | RNFileRef;\nexport type AudioUploadInput = UploadInput;\n\nfunction asError(status: number, body: unknown, message?: string): HibiClientError {\n const err = new Error(message ?? `Hibi API error: ${status}`) as HibiClientError;\n err.status = status;\n err.body = body;\n return err;\n}\n\nfunction isFormData(value: unknown): value is FormData {\n return typeof FormData !== \"undefined\" && value instanceof FormData;\n}\n\nexport function createHibiClient(config: HibiClientConfig) {\n const fetchImpl = config.fetch ?? fetch;\n const base = config.baseUrl.replace(/\\/+$/, \"\");\n\n async function request<T>(\n method: string,\n path: string,\n schema: z.ZodType<T>,\n init: {\n body?: unknown;\n query?: Record<string, string | number | undefined>;\n } = {},\n ): Promise<T> {\n const url = new URL(`${base}${path}`);\n if (init.query) {\n for (const [k, v] of Object.entries(init.query)) {\n if (v !== undefined) url.searchParams.set(k, String(v));\n }\n }\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${config.apiKey}`,\n };\n const requestInit: RequestInit = { method, headers };\n if (init.body !== undefined) {\n if (isFormData(init.body)) {\n // Don't set Content-Type for multipart — the runtime appends\n // the correct boundary. RN in particular breaks if we set it.\n requestInit.body = init.body;\n } else {\n headers[\"Content-Type\"] = \"application/json\";\n requestInit.body = JSON.stringify(init.body);\n }\n }\n\n const res = await fetchImpl(url.toString(), requestInit);\n\n if (res.status === 204) return undefined as T;\n\n const text = await res.text();\n const contentType = res.headers.get(\"content-type\") ?? \"\";\n let body: unknown = null;\n if (text) {\n if (contentType.includes(\"application/json\")) {\n try {\n body = JSON.parse(text);\n } catch (err) {\n throw asError(\n res.status,\n { rawText: text.slice(0, 500), parseError: String(err) },\n `Hibi API ${res.status}: malformed JSON from ${url.toString()} (first 200 chars: ${text.slice(0, 200)})`,\n );\n }\n } else {\n // Non-JSON response — almost always means we hit a misrouted host\n // (Vercel 404 wall, gateway HTML, captive portal). Surface the\n // first chunk of the body so the caller knows where to look.\n throw asError(\n res.status,\n { rawText: text.slice(0, 500), contentType },\n `Hibi API ${res.status}: expected JSON from ${url.toString()} but got ${contentType || \"unknown content-type\"} (first 200 chars: ${text.slice(0, 200)})`,\n );\n }\n }\n\n if (!res.ok) throw asError(res.status, body);\n return schema.parse(body);\n }\n\n function buildUploadForm(input: UploadInput, defaultName: string): FormData {\n const fd = new FormData();\n if (typeof Blob !== \"undefined\" && input instanceof Blob) {\n // Blob/File on web/node20+. Pass a name so the server sees a filename.\n const name = \"name\" in input && typeof input.name === \"string\" ? input.name : defaultName;\n fd.append(\"file\", input, name);\n } else {\n // RN file ref. The cast is unavoidable: RN's FormData accepts this\n // shape but the lib.dom.d.ts FormData type doesn't model it.\n fd.append(\"file\", input as unknown as Blob);\n }\n return fd;\n }\n\n return {\n cards: {\n async create(input: CreateCardInput) {\n const validated = CreateCardInputSchema.parse(input);\n return request(\"POST\", \"/v1/cards\", CardSchema, { body: validated });\n },\n async list(query: ListCardsQuery = { limit: 50 }) {\n return request(\"GET\", \"/v1/cards\", PaginatedCardSchema, {\n query: { limit: query.limit, cursor: query.cursor, tag: query.tag, source: query.source },\n });\n },\n async get(id: string) {\n return request(\"GET\", `/v1/cards/${id}`, CardSchema);\n },\n async update(id: string, input: UpdateCardInput) {\n const validated = UpdateCardInputSchema.parse(input);\n return request(\"PATCH\", `/v1/cards/${id}`, CardSchema, { body: validated });\n },\n async remove(id: string): Promise<void> {\n await request(\"DELETE\", `/v1/cards/${id}`, z.unknown());\n },\n },\n\n uploads: {\n async audio(input: UploadInput) {\n return request(\"POST\", \"/v1/uploads/audio\", UploadResponseSchema, {\n body: buildUploadForm(input, \"clip.m4a\"),\n });\n },\n async image(input: UploadInput) {\n return request(\"POST\", \"/v1/uploads/image\", UploadResponseSchema, {\n body: buildUploadForm(input, \"image.jpg\"),\n });\n },\n },\n\n sessions: {\n async create(input: CreateSessionInput) {\n const validated = CreateSessionInputSchema.parse(input);\n return request(\"POST\", \"/v1/sessions\", SessionSchema, { body: validated });\n },\n async list(query: ListSessionsQuery = { limit: 50 }) {\n const validated = ListSessionsQuerySchema.parse(query);\n return request(\"GET\", \"/v1/sessions\", PaginatedSessionSchema, {\n query: {\n limit: validated.limit,\n cursor: validated.cursor,\n kind: validated.kind,\n source: validated.source,\n from: validated.from,\n to: validated.to,\n },\n });\n },\n },\n\n reviews: {\n async due(query: { limit?: number; before?: string } = {}) {\n return request(\"GET\", \"/v1/reviews/due\", DueResponseSchema, {\n query: { limit: query.limit, before: query.before },\n });\n },\n async submit(input: SubmitReviewInput) {\n const validated = SubmitReviewInputSchema.parse(input);\n return request(\"POST\", \"/v1/reviews\", SubmitReviewResultSchema, { body: validated });\n },\n },\n\n wordStatus: {\n // Upsert (lemma, reading) for the caller; pass status: null to delete.\n async set(input: SetWordStatusInput) {\n const validated = SetWordStatusInputSchema.parse(input);\n return request(\"PUT\", \"/v1/word-status\", NullableManualStatusSchema, {\n body: validated,\n });\n },\n // Paginated list of just the manual rows (no SRS rows).\n async list(query: PaginationQuery = { limit: 50 }) {\n return request(\"GET\", \"/v1/word-status\", PaginatedManualStatusSchema, {\n query: { limit: query.limit, cursor: query.cursor },\n });\n },\n },\n\n knownWords: {\n // Merged manual + SRS classifications. Single source of truth for\n // the underline-by-status view in reading clients.\n async list(query: PaginationQuery = { limit: 50 }) {\n return request(\"GET\", \"/v1/known-words\", PaginatedKnownWordSchema, {\n query: { limit: query.limit, cursor: query.cursor },\n });\n },\n },\n\n stats: {\n async heatmap(query: HeatmapQuery) {\n return request(\"GET\", \"/v1/stats/heatmap\", HeatmapResponseSchema, {\n query: { year: query.year },\n });\n },\n async retention() {\n return request(\"GET\", \"/v1/stats/retention\", RetentionResponseSchema);\n },\n async daily(query: DailyCountQuery) {\n return request(\"GET\", \"/v1/stats/daily\", DailyCountResponseSchema, {\n query: { from: query.from, to: query.to },\n });\n },\n },\n };\n}\n\nexport type HibiClient = ReturnType<typeof createHibiClient>;\n"]}
1
+ {"version":3,"sources":["../src/_vendored/hibi-types/common.ts","../src/_vendored/hibi-types/account.ts","../src/_vendored/hibi-types/ai.ts","../src/_vendored/hibi-types/cards.ts","../src/_vendored/hibi-types/reviews.ts","../src/_vendored/hibi-types/sessions.ts","../src/_vendored/hibi-types/stats.ts","../src/_vendored/hibi-types/word-status.ts","../src/client.ts"],"names":["z"],"mappings":"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","file":"index.js","sourcesContent":["import { z } from \"zod\";\n\nexport const UUIDSchema = z.uuid();\n\nexport const TimestampSchema = z.iso.datetime({ offset: true });\n\nexport const PaginationQuerySchema = z.object({\n limit: z.coerce.number().int().min(1).max(200).default(50),\n cursor: z.string().optional(),\n});\n\nexport type PaginationQuery = z.infer<typeof PaginationQuerySchema>;\n\nexport const PaginatedSchema = <T extends z.ZodTypeAny>(item: T) =>\n z.object({\n items: z.array(item),\n nextCursor: z.string().nullable(),\n });\n\nexport const ErrorResponseSchema = z.object({\n error: z.object({\n code: z.string(),\n message: z.string(),\n details: z.unknown().optional(),\n }),\n});\n\nexport type ErrorResponse = z.infer<typeof ErrorResponseSchema>;\n","import { z } from \"zod\";\nimport { TimestampSchema, UUIDSchema } from \"./common.ts\";\n\nexport const AccountSchema = z.object({\n id: UUIDSchema,\n email: z.email(),\n createdAt: TimestampSchema,\n});\nexport type Account = z.infer<typeof AccountSchema>;\n\nexport const ApiKeySchema = z.object({\n id: UUIDSchema,\n name: z.string().min(1).max(80),\n lastUsedAt: TimestampSchema.nullable(),\n createdAt: TimestampSchema,\n revokedAt: TimestampSchema.nullable(),\n});\nexport type ApiKey = z.infer<typeof ApiKeySchema>;\n\nexport const CreateApiKeyInputSchema = z.object({\n name: z.string().min(1).max(80),\n});\nexport type CreateApiKeyInput = z.infer<typeof CreateApiKeyInputSchema>;\n\nexport const CreateApiKeyResponseSchema = z.object({\n apiKey: ApiKeySchema,\n rawKey: z.string(),\n});\nexport type CreateApiKeyResponse = z.infer<typeof CreateApiKeyResponseSchema>;\n\nexport const SaveOpenRouterKeyInputSchema = z.object({\n apiKey: z.string().min(1).max(512),\n});\nexport type SaveOpenRouterKeyInput = z.infer<typeof SaveOpenRouterKeyInputSchema>;\n\n// Returned by PUT /v1/account/openrouter-key after a successful probe.\n// Mirrors the fields OpenRouter's GET /auth/key exposes.\nexport const OpenRouterKeyInfoSchema = z.object({\n label: z.string(),\n usage: z.number().nullable(),\n limit: z.number().nullable(),\n});\nexport type OpenRouterKeyInfo = z.infer<typeof OpenRouterKeyInfoSchema>;\n\nexport const OpenRouterKeyStatusSchema = z.object({\n configured: z.boolean(),\n keyLabel: z.string().nullable().optional(),\n updatedAt: TimestampSchema.nullable().optional(),\n});\nexport type OpenRouterKeyStatus = z.infer<typeof OpenRouterKeyStatusSchema>;\n","import { z } from \"zod\";\n\n// Returned by GET /v1/ai/key (client API-key authed). The discovery\n// endpoint for AI features: lets a client decide whether to surface\n// the \"configure OpenRouter in portal\" prompt before invoking proxy\n// routes.\nexport const ClientAiStatusSchema = z.discriminatedUnion(\"configured\", [\n z.object({\n configured: z.literal(true),\n label: z.string(),\n usage: z.number().nullable(),\n limit: z.number().nullable(),\n }),\n z.object({\n configured: z.literal(false),\n }),\n]);\nexport type ClientAiStatus = z.infer<typeof ClientAiStatusSchema>;\n","import { z } from \"zod\";\nimport { TimestampSchema, UUIDSchema } from \"./common.ts\";\n\nexport const FuriganaPairSchema = z.object({\n base: z.string(),\n reading: z.string(),\n});\nexport type FuriganaPair = z.infer<typeof FuriganaPairSchema>;\n\nexport const KanjiEntrySchema = z.object({\n kanji: z.string().length(1),\n meaning: z.string(),\n wanikaniLevel: z.number().int().min(1).max(60).nullable(),\n});\nexport type KanjiEntry = z.infer<typeof KanjiEntrySchema>;\n\nexport const CardSchema = z.object({\n id: UUIDSchema,\n userId: UUIDSchema,\n createdAt: TimestampSchema,\n updatedAt: TimestampSchema,\n\n sentence: z.string().min(1),\n focusWord: z.string().min(1),\n focusWordReading: z.string().min(1),\n furigana: z.array(FuriganaPairSchema),\n english: z.string(),\n glosses: z.array(z.string()),\n grammarNote: z.string().nullable(),\n kanjiList: z.array(KanjiEntrySchema),\n\n imageKey: z.string().nullable(),\n audioKey: z.string().nullable(),\n imageUrl: z.string().url().nullable(),\n audioUrl: z.string().url().nullable(),\n\n source: z.string(),\n tags: z.array(z.string()),\n});\nexport type Card = z.infer<typeof CardSchema>;\n\nexport const CreateCardInputSchema = CardSchema.omit({\n id: true,\n userId: true,\n createdAt: true,\n updatedAt: true,\n imageUrl: true,\n audioUrl: true,\n});\nexport type CreateCardInput = z.infer<typeof CreateCardInputSchema>;\n\nexport const UpdateCardInputSchema = CreateCardInputSchema.partial();\nexport type UpdateCardInput = z.infer<typeof UpdateCardInputSchema>;\n\nexport const ListCardsSortSchema = z.enum([\"newest\", \"oldest\", \"due-soonest\"]);\nexport type ListCardsSort = z.infer<typeof ListCardsSortSchema>;\n\nexport const ListCardsQuerySchema = z.object({\n limit: z.coerce.number().int().min(1).max(200).default(50),\n cursor: z.string().optional(),\n tag: z.string().optional(),\n source: z.string().optional(),\n q: z.string().min(1).max(200).optional(),\n sort: ListCardsSortSchema.default(\"newest\"),\n});\nexport type ListCardsQuery = z.infer<typeof ListCardsQuerySchema>;\n","import { z } from \"zod\";\nimport { TimestampSchema, UUIDSchema } from \"./common.ts\";\n\nexport const CardStateSchema = z.enum([\"new\", \"learning\", \"review\", \"relearning\"]);\nexport type CardStateValue = z.infer<typeof CardStateSchema>;\n\nexport const ReviewRatingSchema = z.union([z.literal(1), z.literal(2), z.literal(3), z.literal(4)]);\nexport type ReviewRating = z.infer<typeof ReviewRatingSchema>;\n\nexport const ReviewSchema = z.object({\n id: UUIDSchema,\n userId: UUIDSchema,\n cardId: UUIDSchema,\n rating: ReviewRatingSchema,\n reviewedAt: TimestampSchema,\n elapsedDays: z.number(),\n scheduledDays: z.number(),\n stateBefore: CardStateSchema,\n stateAfter: CardStateSchema,\n});\nexport type Review = z.infer<typeof ReviewSchema>;\n\nexport const CardStateRowSchema = z.object({\n cardId: UUIDSchema,\n userId: UUIDSchema,\n due: TimestampSchema,\n stability: z.number(),\n difficulty: z.number(),\n elapsedDays: z.number(),\n scheduledDays: z.number(),\n reps: z.number().int().nonnegative(),\n lapses: z.number().int().nonnegative(),\n learningSteps: z.number().int().nonnegative(),\n state: CardStateSchema,\n lastReview: TimestampSchema.nullable(),\n});\nexport type CardStateRow = z.infer<typeof CardStateRowSchema>;\n\nexport const DueReviewsQuerySchema = z.object({\n limit: z.coerce.number().int().min(1).max(200).default(50),\n before: TimestampSchema.optional(),\n});\nexport type DueReviewsQuery = z.infer<typeof DueReviewsQuerySchema>;\n\nexport const SubmitReviewInputSchema = z.object({\n cardId: UUIDSchema,\n rating: ReviewRatingSchema,\n reviewedAt: TimestampSchema.optional(),\n});\nexport type SubmitReviewInput = z.infer<typeof SubmitReviewInputSchema>;\n\nexport const SubmitReviewResultSchema = z.object({\n review: ReviewSchema,\n cardState: CardStateRowSchema,\n});\nexport type SubmitReviewResult = z.infer<typeof SubmitReviewResultSchema>;\n","import { z } from \"zod\";\nimport { TimestampSchema, UUIDSchema } from \"./common.ts\";\n\n// Free-form per-app context (e.g. { trackId } for Hibi Koe). Keep as\n// a record so future apps can attach their own keys without a type bump.\nexport const SessionMetadataSchema = z.record(z.string(), z.unknown()).nullable();\n\nexport const SessionSchema = z.object({\n id: UUIDSchema,\n userId: UUIDSchema,\n kind: z.string().min(1),\n source: z.string().min(1),\n startedAt: TimestampSchema,\n endedAt: TimestampSchema,\n durationMs: z.number().int().nonnegative(),\n metadata: SessionMetadataSchema,\n createdAt: TimestampSchema,\n});\nexport type Session = z.infer<typeof SessionSchema>;\n\nexport const CreateSessionInputSchema = SessionSchema.omit({\n id: true,\n userId: true,\n createdAt: true,\n}).extend({\n metadata: SessionMetadataSchema.optional(),\n});\nexport type CreateSessionInput = z.infer<typeof CreateSessionInputSchema>;\n\nexport const ListSessionsQuerySchema = z.object({\n limit: z.coerce.number().int().min(1).max(200).default(50),\n cursor: z.string().optional(),\n kind: z.string().optional(),\n source: z.string().optional(),\n // Inclusive lower bound, exclusive upper. Both ISO-8601 timestamps.\n from: z.iso.datetime({ offset: true }).optional(),\n to: z.iso.datetime({ offset: true }).optional(),\n});\nexport type ListSessionsQuery = z.infer<typeof ListSessionsQuerySchema>;\n","import { z } from \"zod\";\nimport { TimestampSchema } from \"./common.ts\";\n\nexport const HeatmapDaySchema = z.object({\n date: z.iso.date(),\n count: z.number().int().nonnegative(),\n});\nexport type HeatmapDay = z.infer<typeof HeatmapDaySchema>;\n\nexport const HeatmapQuerySchema = z.object({\n year: z.coerce.number().int().min(2000).max(2100),\n});\nexport type HeatmapQuery = z.infer<typeof HeatmapQuerySchema>;\n\nexport const HeatmapResponseSchema = z.object({\n year: z.number().int(),\n days: z.array(HeatmapDaySchema),\n});\nexport type HeatmapResponse = z.infer<typeof HeatmapResponseSchema>;\n\nexport const RetentionPointSchema = z.object({\n intervalDays: z.number().int().nonnegative(),\n retention: z.number().min(0).max(1),\n sampleSize: z.number().int().nonnegative(),\n});\nexport type RetentionPoint = z.infer<typeof RetentionPointSchema>;\n\nexport const RetentionResponseSchema = z.object({\n generatedAt: TimestampSchema,\n points: z.array(RetentionPointSchema),\n});\nexport type RetentionResponse = z.infer<typeof RetentionResponseSchema>;\n\nexport const DailyCountQuerySchema = z.object({\n from: z.iso.date(),\n to: z.iso.date(),\n});\nexport type DailyCountQuery = z.infer<typeof DailyCountQuerySchema>;\n\nexport const DailyCountSchema = z.object({\n date: z.iso.date(),\n reviews: z.number().int().nonnegative(),\n again: z.number().int().nonnegative(),\n hard: z.number().int().nonnegative(),\n good: z.number().int().nonnegative(),\n easy: z.number().int().nonnegative(),\n});\nexport type DailyCount = z.infer<typeof DailyCountSchema>;\n\nexport const DailyCountResponseSchema = z.object({\n days: z.array(DailyCountSchema),\n});\nexport type DailyCountResponse = z.infer<typeof DailyCountResponseSchema>;\n","import { z } from \"zod\";\nimport { TimestampSchema, UUIDSchema } from \"./common.ts\";\n\n// Three writeable values. 'unknown' is the implicit default and is\n// represented by the absence of a row, never stored explicitly.\nexport const WordStatusSchema = z.enum([\"learning\", \"known\", \"ignored\"]);\nexport type WordStatus = z.infer<typeof WordStatusSchema>;\n\n// Manual word-status row as the user set it. (lemma, reading) is unique\n// per-user; updating with the same key overwrites status + updatedAt.\nexport const ManualWordStatusSchema = z.object({\n id: UUIDSchema,\n lemma: z.string().min(1),\n reading: z.string().min(1),\n status: WordStatusSchema,\n createdAt: TimestampSchema,\n updatedAt: TimestampSchema,\n});\nexport type ManualWordStatus = z.infer<typeof ManualWordStatusSchema>;\n\n// PUT /v1/word-status body. status: null deletes the row.\nexport const SetWordStatusInputSchema = z.object({\n lemma: z.string().min(1),\n reading: z.string().min(1),\n status: WordStatusSchema.nullable(),\n});\nexport type SetWordStatusInput = z.infer<typeof SetWordStatusInputSchema>;\n\n// One row in the merged /v1/known-words response. source distinguishes\n// manual marks from SRS-derived classifications. When source is 'srs',\n// cardId + intervalDays are populated; clients should treat the status\n// as read-only and tell users to adjust by reviewing the card.\nexport const KnownWordSchema = z.object({\n lemma: z.string(),\n reading: z.string(),\n status: WordStatusSchema,\n source: z.enum([\"manual\", \"srs\"]),\n cardId: UUIDSchema.nullable(),\n intervalDays: z.number().int().nullable(),\n updatedAt: TimestampSchema,\n});\nexport type KnownWord = z.infer<typeof KnownWordSchema>;\n","import { z } from \"zod\";\nimport {\n CardSchema,\n ClientAiStatusSchema,\n type CreateCardInput,\n CreateCardInputSchema,\n type DailyCountQuery,\n DailyCountResponseSchema,\n type HeatmapQuery,\n HeatmapResponseSchema,\n KnownWordSchema,\n type ListCardsQuery,\n ManualWordStatusSchema,\n PaginatedSchema,\n type PaginationQuery,\n RetentionResponseSchema,\n CreateSessionInputSchema,\n type CreateSessionInput,\n type SetWordStatusInput,\n SetWordStatusInputSchema,\n ListSessionsQuerySchema,\n type ListSessionsQuery,\n SessionSchema,\n type SubmitReviewInput,\n SubmitReviewInputSchema,\n SubmitReviewResultSchema,\n type UpdateCardInput,\n UpdateCardInputSchema,\n} from \"./_vendored/hibi-types/index.ts\";\n\nexport interface HibiClientConfig {\n apiKey: string;\n baseUrl: string;\n fetch?: typeof fetch;\n}\n\nexport interface HibiClientError extends Error {\n status: number;\n body: unknown;\n}\n\nconst PaginatedCardSchema = PaginatedSchema(CardSchema);\nconst PaginatedSessionSchema = PaginatedSchema(SessionSchema);\nconst PaginatedManualStatusSchema = PaginatedSchema(ManualWordStatusSchema);\nconst PaginatedKnownWordSchema = PaginatedSchema(KnownWordSchema);\nconst NullableManualStatusSchema = ManualWordStatusSchema.nullable();\nconst DueResponseSchema = z.object({\n items: z.array(\n z.object({ card: CardSchema, cardState: SubmitReviewResultSchema.shape.cardState }),\n ),\n});\nconst UploadResponseSchema = z.object({ key: z.string() });\n\n// React-Native-style file reference. RN's FormData.append accepts this\n// shape directly; we type it explicitly so consumers can build it\n// without depending on RN-specific globals.\nexport type RNFileRef = { uri: string; name: string; type: string };\n\n// What client.uploads.* accepts. On web pass a Blob/File; on RN pass an\n// RNFileRef. In both cases the SDK builds the multipart body.\nexport type UploadInput = Blob | RNFileRef;\nexport type AudioUploadInput = UploadInput;\n\nfunction asError(status: number, body: unknown, message?: string): HibiClientError {\n const err = new Error(message ?? `Hibi API error: ${status}`) as HibiClientError;\n err.status = status;\n err.body = body;\n return err;\n}\n\nfunction isFormData(value: unknown): value is FormData {\n return typeof FormData !== \"undefined\" && value instanceof FormData;\n}\n\nexport function createHibiClient(config: HibiClientConfig) {\n const fetchImpl = config.fetch ?? fetch;\n const base = config.baseUrl.replace(/\\/+$/, \"\");\n\n async function request<T>(\n method: string,\n path: string,\n schema: z.ZodType<T>,\n init: {\n body?: unknown;\n query?: Record<string, string | number | undefined>;\n } = {},\n ): Promise<T> {\n const url = new URL(`${base}${path}`);\n if (init.query) {\n for (const [k, v] of Object.entries(init.query)) {\n if (v !== undefined) url.searchParams.set(k, String(v));\n }\n }\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${config.apiKey}`,\n };\n const requestInit: RequestInit = { method, headers };\n if (init.body !== undefined) {\n if (isFormData(init.body)) {\n // Don't set Content-Type for multipart — the runtime appends\n // the correct boundary. RN in particular breaks if we set it.\n requestInit.body = init.body;\n } else {\n headers[\"Content-Type\"] = \"application/json\";\n requestInit.body = JSON.stringify(init.body);\n }\n }\n\n const res = await fetchImpl(url.toString(), requestInit);\n\n if (res.status === 204) return undefined as T;\n\n const text = await res.text();\n const contentType = res.headers.get(\"content-type\") ?? \"\";\n let body: unknown = null;\n if (text) {\n if (contentType.includes(\"application/json\")) {\n try {\n body = JSON.parse(text);\n } catch (err) {\n throw asError(\n res.status,\n { rawText: text.slice(0, 500), parseError: String(err) },\n `Hibi API ${res.status}: malformed JSON from ${url.toString()} (first 200 chars: ${text.slice(0, 200)})`,\n );\n }\n } else {\n // Non-JSON response — almost always means we hit a misrouted host\n // (Vercel 404 wall, gateway HTML, captive portal). Surface the\n // first chunk of the body so the caller knows where to look.\n throw asError(\n res.status,\n { rawText: text.slice(0, 500), contentType },\n `Hibi API ${res.status}: expected JSON from ${url.toString()} but got ${contentType || \"unknown content-type\"} (first 200 chars: ${text.slice(0, 200)})`,\n );\n }\n }\n\n if (!res.ok) throw asError(res.status, body);\n return schema.parse(body);\n }\n\n // Like request() but returns the raw Response without parsing. Used by\n // /v1/ai/* proxy routes where the response body might be SSE, binary\n // audio, or OR-shaped JSON we deliberately don't validate.\n async function requestRaw(\n method: string,\n path: string,\n init: { body?: unknown; query?: Record<string, string | number | undefined> } = {},\n ): Promise<Response> {\n const url = new URL(`${base}${path}`);\n if (init.query) {\n for (const [k, v] of Object.entries(init.query)) {\n if (v !== undefined) url.searchParams.set(k, String(v));\n }\n }\n const headers: Record<string, string> = {\n Authorization: `Bearer ${config.apiKey}`,\n };\n const requestInit: RequestInit = { method, headers };\n if (init.body !== undefined) {\n headers[\"Content-Type\"] = \"application/json\";\n requestInit.body = JSON.stringify(init.body);\n }\n const res = await fetchImpl(url.toString(), requestInit);\n if (!res.ok) {\n const text = await res.text();\n let body: unknown = text;\n try {\n body = JSON.parse(text);\n } catch {\n // keep as text\n }\n throw asError(res.status, body);\n }\n return res;\n }\n\n function buildUploadForm(input: UploadInput, defaultName: string): FormData {\n const fd = new FormData();\n if (typeof Blob !== \"undefined\" && input instanceof Blob) {\n // Blob/File on web/node20+. Pass a name so the server sees a filename.\n const name = \"name\" in input && typeof input.name === \"string\" ? input.name : defaultName;\n fd.append(\"file\", input, name);\n } else {\n // RN file ref. The cast is unavoidable: RN's FormData accepts this\n // shape but the lib.dom.d.ts FormData type doesn't model it.\n fd.append(\"file\", input as unknown as Blob);\n }\n return fd;\n }\n\n return {\n cards: {\n async create(input: CreateCardInput) {\n const validated = CreateCardInputSchema.parse(input);\n return request(\"POST\", \"/v1/cards\", CardSchema, { body: validated });\n },\n async list(query: ListCardsQuery = { limit: 50, sort: \"newest\" }) {\n return request(\"GET\", \"/v1/cards\", PaginatedCardSchema, {\n query: {\n limit: query.limit,\n cursor: query.cursor,\n tag: query.tag,\n source: query.source,\n q: query.q,\n sort: query.sort,\n },\n });\n },\n async get(id: string) {\n return request(\"GET\", `/v1/cards/${id}`, CardSchema);\n },\n async update(id: string, input: UpdateCardInput) {\n const validated = UpdateCardInputSchema.parse(input);\n return request(\"PATCH\", `/v1/cards/${id}`, CardSchema, { body: validated });\n },\n async remove(id: string): Promise<void> {\n await request(\"DELETE\", `/v1/cards/${id}`, z.unknown());\n },\n },\n\n uploads: {\n async audio(input: UploadInput) {\n return request(\"POST\", \"/v1/uploads/audio\", UploadResponseSchema, {\n body: buildUploadForm(input, \"clip.m4a\"),\n });\n },\n async image(input: UploadInput) {\n return request(\"POST\", \"/v1/uploads/image\", UploadResponseSchema, {\n body: buildUploadForm(input, \"image.jpg\"),\n });\n },\n },\n\n sessions: {\n async create(input: CreateSessionInput) {\n const validated = CreateSessionInputSchema.parse(input);\n return request(\"POST\", \"/v1/sessions\", SessionSchema, { body: validated });\n },\n async list(query: ListSessionsQuery = { limit: 50 }) {\n const validated = ListSessionsQuerySchema.parse(query);\n return request(\"GET\", \"/v1/sessions\", PaginatedSessionSchema, {\n query: {\n limit: validated.limit,\n cursor: validated.cursor,\n kind: validated.kind,\n source: validated.source,\n from: validated.from,\n to: validated.to,\n },\n });\n },\n },\n\n reviews: {\n async due(query: { limit?: number; before?: string } = {}) {\n return request(\"GET\", \"/v1/reviews/due\", DueResponseSchema, {\n query: { limit: query.limit, before: query.before },\n });\n },\n async submit(input: SubmitReviewInput) {\n const validated = SubmitReviewInputSchema.parse(input);\n return request(\"POST\", \"/v1/reviews\", SubmitReviewResultSchema, { body: validated });\n },\n },\n\n wordStatus: {\n // Upsert (lemma, reading) for the caller; pass status: null to delete.\n async set(input: SetWordStatusInput) {\n const validated = SetWordStatusInputSchema.parse(input);\n return request(\"PUT\", \"/v1/word-status\", NullableManualStatusSchema, {\n body: validated,\n });\n },\n // Paginated list of just the manual rows (no SRS rows).\n async list(query: PaginationQuery = { limit: 50 }) {\n return request(\"GET\", \"/v1/word-status\", PaginatedManualStatusSchema, {\n query: { limit: query.limit, cursor: query.cursor },\n });\n },\n },\n\n knownWords: {\n // Merged manual + SRS classifications. Single source of truth for\n // the underline-by-status view in reading clients.\n async list(query: PaginationQuery = { limit: 50 }) {\n return request(\"GET\", \"/v1/known-words\", PaginatedKnownWordSchema, {\n query: { limit: query.limit, cursor: query.cursor },\n });\n },\n },\n\n stats: {\n async heatmap(query: HeatmapQuery) {\n return request(\"GET\", \"/v1/stats/heatmap\", HeatmapResponseSchema, {\n query: { year: query.year },\n });\n },\n async retention() {\n return request(\"GET\", \"/v1/stats/retention\", RetentionResponseSchema);\n },\n async daily(query: DailyCountQuery) {\n return request(\"GET\", \"/v1/stats/daily\", DailyCountResponseSchema, {\n query: { from: query.from, to: query.to },\n });\n },\n },\n\n ai: {\n // Discovery: is the user's OpenRouter key configured server-side?\n // Hit this on app start before surfacing AI-dependent UI.\n async key() {\n return request(\"GET\", \"/v1/ai/key\", ClientAiStatusSchema);\n },\n // OpenRouter chat completions, proxied. Returns the raw Response\n // so the caller can stream from res.body (when stream:true) or\n // call res.json() (when stream:false).\n async chatCompletions(body: Record<string, unknown>) {\n return requestRaw(\"POST\", \"/v1/ai/chat/completions\", { body });\n },\n audio: {\n async transcriptions(body: Record<string, unknown>): Promise<unknown> {\n const res = await requestRaw(\"POST\", \"/v1/ai/audio/transcriptions\", { body });\n return res.json();\n },\n // Returns the raw audio bytes (MP3 by default).\n async speech(body: Record<string, unknown>): Promise<Uint8Array> {\n const res = await requestRaw(\"POST\", \"/v1/ai/audio/speech\", { body });\n return new Uint8Array(await res.arrayBuffer());\n },\n },\n },\n };\n}\n\nexport type HibiClient = ReturnType<typeof createHibiClient>;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hibi-client",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "Official TypeScript client for the Hibi flashcard API.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -39,12 +39,6 @@
39
39
  "sentence-mining"
40
40
  ],
41
41
  "author": "yannickhrr",
42
- "scripts": {
43
- "build": "tsup",
44
- "dev": "tsup --watch",
45
- "typecheck": "tsc --noEmit",
46
- "test": "vitest run --passWithNoTests"
47
- },
48
42
  "dependencies": {
49
43
  "zod": "4.4.3"
50
44
  },
@@ -52,5 +46,11 @@
52
46
  "tsup": "8.5.1",
53
47
  "typescript": "6.0.3",
54
48
  "vitest": "4.1.5"
49
+ },
50
+ "scripts": {
51
+ "build": "tsup",
52
+ "dev": "tsup --watch",
53
+ "typecheck": "tsc --noEmit",
54
+ "test": "vitest run --passWithNoTests"
55
55
  }
56
- }
56
+ }