@minimoth/sdk-node 0.1.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/dist/index.cjs ADDED
@@ -0,0 +1,556 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ MiniMoth: () => MiniMoth,
34
+ MiniMothError: () => MiniMothError
35
+ });
36
+ module.exports = __toCommonJS(index_exports);
37
+
38
+ // node_modules/tsup/assets/cjs_shims.js
39
+ var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.tagName.toUpperCase() === "SCRIPT" ? document.currentScript.src : new URL("main.js", document.baseURI).href;
40
+ var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
41
+
42
+ // src/otp/OtpClient.ts
43
+ var import_jsonwebtoken = __toESM(require("jsonwebtoken"), 1);
44
+
45
+ // src/MiniMothError.ts
46
+ var MiniMothError = class extends Error {
47
+ code;
48
+ statusCode;
49
+ constructor(code, message, statusCode, cause) {
50
+ super(message, cause !== void 0 ? { cause } : void 0);
51
+ this.name = "MiniMothError";
52
+ this.code = code;
53
+ this.statusCode = statusCode;
54
+ Object.setPrototypeOf(this, new.target.prototype);
55
+ }
56
+ };
57
+
58
+ // src/http.ts
59
+ var import_module = require("module");
60
+ var require2 = (0, import_module.createRequire)(importMetaUrl);
61
+ var pkg = require2("../package.json");
62
+ var BASE_URL = "https://api.minimoth.dev";
63
+ var USER_AGENT = `minimoth-sdk-node/${pkg.version}`;
64
+ var BACKEND_CODE_MAP = {
65
+ INVALID_ACCESS_TOKEN: "INVALID_TOKEN",
66
+ TOKEN_EXPIRED: "TOKEN_EXPIRED",
67
+ TOKEN_REVOKED: "TOKEN_REVOKED",
68
+ INVALID_OTP: "INVALID_OTP",
69
+ OTP_NOT_FOUND: "OTP_EXPIRED",
70
+ OTP_RATE_LIMITED: "RATE_LIMITED",
71
+ VERIFY_RATE_LIMITED: "RATE_LIMITED",
72
+ INSUFFICIENT_BALANCE: "INSUFFICIENT_BALANCE",
73
+ INVALID_PHONE: "INVALID_PHONE"
74
+ };
75
+ async function handleResponse(response) {
76
+ if (response.ok) return response.json();
77
+ let body = {};
78
+ try {
79
+ body = await response.json();
80
+ } catch {
81
+ }
82
+ const sdkCode = BACKEND_CODE_MAP[body.code ?? ""] ?? "UNKNOWN_ERROR";
83
+ throw new MiniMothError(sdkCode, body.error ?? "Unknown error", response.status);
84
+ }
85
+ async function apiPost(path, apiKey, body) {
86
+ let response;
87
+ try {
88
+ response = await fetch(`${BASE_URL}${path}`, {
89
+ method: "POST",
90
+ headers: {
91
+ "Content-Type": "application/json",
92
+ "X-Api-Key": apiKey,
93
+ "User-Agent": USER_AGENT
94
+ },
95
+ body: JSON.stringify(body)
96
+ });
97
+ } catch (err) {
98
+ throw new MiniMothError("NETWORK_ERROR", "Network request failed", 0, err);
99
+ }
100
+ return handleResponse(response);
101
+ }
102
+ async function apiGet(path) {
103
+ let response;
104
+ try {
105
+ response = await fetch(`${BASE_URL}${path}`, {
106
+ headers: { "User-Agent": USER_AGENT }
107
+ });
108
+ } catch (err) {
109
+ throw new MiniMothError("NETWORK_ERROR", "Network request failed", 0, err);
110
+ }
111
+ return handleResponse(response);
112
+ }
113
+
114
+ // src/otp/OtpClient.ts
115
+ var OtpClient = class {
116
+ constructor(apiKey, store, logger) {
117
+ this.apiKey = apiKey;
118
+ this.store = store;
119
+ this.logger = logger;
120
+ }
121
+ apiKey;
122
+ store;
123
+ logger;
124
+ async send(params) {
125
+ const phone = normalizePhone(params.phone);
126
+ await apiPost("/v1/otp/send", this.apiKey, { phone });
127
+ this.logger.info("otp.sent", { phone: maskPhone(phone) });
128
+ }
129
+ async verify(params) {
130
+ const phone = normalizePhone(params.phone);
131
+ validateOtp(params.otp);
132
+ try {
133
+ const res = await apiPost(
134
+ "/v1/otp/verify",
135
+ this.apiKey,
136
+ { phone, code: params.otp }
137
+ );
138
+ const payload = import_jsonwebtoken.default.decode(res.access_token);
139
+ if (!payload?.session_id) {
140
+ throw new MiniMothError("INVALID_TOKEN", "Could not decode session_id from access token", 0);
141
+ }
142
+ try {
143
+ await this.store.setTokens(payload.session_id, {
144
+ accessToken: res.access_token,
145
+ refreshToken: res.refresh_token
146
+ });
147
+ } catch {
148
+ this.logger.error("otp.store.setTokens.failed", { sessionId: payload.session_id.slice(0, 8) });
149
+ }
150
+ this.logger.info("otp.verified", { sessionId: payload.session_id.slice(0, 8) });
151
+ return {
152
+ valid: true,
153
+ accessToken: res.access_token,
154
+ refreshToken: res.refresh_token,
155
+ sessionId: payload.session_id
156
+ };
157
+ } catch (err) {
158
+ if (err instanceof MiniMothError) {
159
+ if (err.code === "INVALID_OTP" || err.code === "OTP_EXPIRED" || err.code === "INVALID_PHONE") {
160
+ this.logger.debug("otp.verify.failed", { code: err.code });
161
+ return { valid: false, code: err.code };
162
+ }
163
+ }
164
+ throw err;
165
+ }
166
+ }
167
+ };
168
+ function normalizePhone(raw) {
169
+ if (!raw || typeof raw !== "string") {
170
+ throw new MiniMothError("INVALID_PHONE", "Phone number is required", 422);
171
+ }
172
+ if (/[\s-]/.test(raw)) {
173
+ throw new MiniMothError("INVALID_PHONE", "Phone number must not contain spaces or hyphens", 422);
174
+ }
175
+ let phone = raw;
176
+ if (phone.startsWith("+")) phone = phone.slice(1);
177
+ if (phone.length === 10) phone = "91" + phone;
178
+ return phone;
179
+ }
180
+ function validateOtp(otp) {
181
+ if (!otp || typeof otp !== "string") {
182
+ throw new MiniMothError("INVALID_OTP", "OTP is required", 422);
183
+ }
184
+ }
185
+ function maskPhone(phone) {
186
+ if (phone.length <= 4) return "****";
187
+ return phone.slice(0, 4) + "*".repeat(Math.max(phone.length - 6, 1)) + phone.slice(-2);
188
+ }
189
+
190
+ // src/session/SessionClient.ts
191
+ var import_jsonwebtoken2 = __toESM(require("jsonwebtoken"), 1);
192
+ var SessionClient = class {
193
+ constructor(apiKey, jwksCache, revocationCache, deduplicator, store, logger) {
194
+ this.apiKey = apiKey;
195
+ this.jwksCache = jwksCache;
196
+ this.revocationCache = revocationCache;
197
+ this.deduplicator = deduplicator;
198
+ this.store = store;
199
+ this.logger = logger;
200
+ }
201
+ apiKey;
202
+ jwksCache;
203
+ revocationCache;
204
+ deduplicator;
205
+ store;
206
+ logger;
207
+ async validate(accessToken) {
208
+ const decoded = import_jsonwebtoken2.default.decode(accessToken, { complete: true });
209
+ if (!decoded || typeof decoded === "string") {
210
+ throw new MiniMothError("INVALID_TOKEN", "Token is malformed", 401);
211
+ }
212
+ const kid = decoded.header["kid"];
213
+ if (!kid) throw new MiniMothError("INVALID_TOKEN", "Token is missing kid header", 401);
214
+ const publicKey = await this.jwksCache.getKey(kid);
215
+ let currentToken = accessToken;
216
+ let newTokens;
217
+ try {
218
+ import_jsonwebtoken2.default.verify(accessToken, publicKey, { algorithms: ["RS256"] });
219
+ } catch (err) {
220
+ if (err instanceof import_jsonwebtoken2.default.TokenExpiredError) {
221
+ const expiredPayload = decoded.payload;
222
+ const sessionId = expiredPayload?.session_id;
223
+ if (!sessionId) throw new MiniMothError("INVALID_TOKEN", "Token is invalid", 401);
224
+ newTokens = await this.deduplicator.getOrRun(sessionId, async () => {
225
+ const refreshToken = await this.store.getRefreshToken(sessionId);
226
+ if (!refreshToken) {
227
+ throw new MiniMothError("TOKEN_EXPIRED", "Access token expired and no refresh token available", 401);
228
+ }
229
+ this.logger.info("session.auto_refresh", { sessionId: sessionId.slice(0, 8) });
230
+ const res = await apiPost(
231
+ "/v1/session/refresh",
232
+ this.apiKey,
233
+ { refresh_token: refreshToken }
234
+ );
235
+ try {
236
+ await this.store.setTokens(sessionId, {
237
+ accessToken: res.access_token,
238
+ refreshToken: res.refresh_token
239
+ });
240
+ } catch (err2) {
241
+ this.logger.error("session.store.setTokens.failed", { sessionId: sessionId.slice(0, 8) });
242
+ }
243
+ return { accessToken: res.access_token, refreshToken: res.refresh_token };
244
+ });
245
+ currentToken = newTokens.accessToken;
246
+ const newDecoded = import_jsonwebtoken2.default.decode(currentToken, { complete: true });
247
+ const newKid = newDecoded?.header?.["kid"];
248
+ const newKey = newKid ? await this.jwksCache.getKey(newKid) : publicKey;
249
+ import_jsonwebtoken2.default.verify(currentToken, newKey, { algorithms: ["RS256"] });
250
+ } else {
251
+ throw new MiniMothError("INVALID_TOKEN", "Token signature is invalid", 401);
252
+ }
253
+ }
254
+ const payload = import_jsonwebtoken2.default.decode(currentToken);
255
+ const isValid = await this.revocationCache.check(payload.jti, currentToken);
256
+ if (!isValid) throw new MiniMothError("TOKEN_REVOKED", "Session has been revoked", 401);
257
+ const session = {
258
+ phone: payload.sub,
259
+ projectId: payload.project_id,
260
+ sessionId: payload.session_id,
261
+ expiresAt: new Date(payload.exp * 1e3)
262
+ };
263
+ if (newTokens) session.newTokens = newTokens;
264
+ this.logger.info("session.validated", { sessionId: payload.session_id.slice(0, 8) });
265
+ return session;
266
+ }
267
+ async safeValidate(accessToken) {
268
+ try {
269
+ const session = await this.validate(accessToken);
270
+ return { valid: true, session };
271
+ } catch (err) {
272
+ if (err instanceof MiniMothError) return { valid: false, code: err.code };
273
+ throw err;
274
+ }
275
+ }
276
+ async refresh(refreshToken) {
277
+ const res = await apiPost(
278
+ "/v1/session/refresh",
279
+ this.apiKey,
280
+ { refresh_token: refreshToken }
281
+ );
282
+ const payload = import_jsonwebtoken2.default.decode(res.access_token);
283
+ if (payload?.session_id) {
284
+ try {
285
+ await this.store.setTokens(payload.session_id, {
286
+ accessToken: res.access_token,
287
+ refreshToken: res.refresh_token
288
+ });
289
+ } catch (err) {
290
+ this.logger.error("session.store.setTokens.failed", { sessionId: payload.session_id.slice(0, 8) });
291
+ }
292
+ }
293
+ this.logger.info("session.refreshed");
294
+ return { accessToken: res.access_token, refreshToken: res.refresh_token };
295
+ }
296
+ async logout(params) {
297
+ const payload = import_jsonwebtoken2.default.decode(params.accessToken);
298
+ const sessionId = payload?.session_id ?? null;
299
+ if (!sessionId) throw new MiniMothError("INVALID_TOKEN", "Cannot decode token", 401);
300
+ let currentAccessToken = params.accessToken;
301
+ if (payload && payload.exp < Math.floor(Date.now() / 1e3)) {
302
+ const newTokens = await this.deduplicator.getOrRun(sessionId, async () => {
303
+ const res = await apiPost(
304
+ "/v1/session/refresh",
305
+ this.apiKey,
306
+ { refresh_token: params.refreshToken }
307
+ );
308
+ return { accessToken: res.access_token, refreshToken: res.refresh_token };
309
+ });
310
+ currentAccessToken = newTokens.accessToken;
311
+ try {
312
+ await this.store.setTokens(sessionId, newTokens);
313
+ } catch (err) {
314
+ this.logger.error("session.store.setTokens.failed", { sessionId: sessionId.slice(0, 8) });
315
+ }
316
+ }
317
+ await apiPost(
318
+ "/v1/session/logout",
319
+ this.apiKey,
320
+ { access_token: currentAccessToken }
321
+ );
322
+ try {
323
+ await this.store.deleteSession(sessionId);
324
+ } catch (err) {
325
+ this.logger.error("session.store.deleteSession.failed", { sessionId: sessionId.slice(0, 8) });
326
+ }
327
+ this.logger.info("session.logged_out", { sessionId: sessionId.slice(0, 8) });
328
+ }
329
+ };
330
+
331
+ // src/session/JwksCache.ts
332
+ var import_crypto = __toESM(require("crypto"), 1);
333
+ var CACHE_TTL_MS = 60 * 60 * 1e3;
334
+ var JwksCache = class {
335
+ constructor(logger) {
336
+ this.logger = logger;
337
+ }
338
+ logger;
339
+ keyMap = /* @__PURE__ */ new Map();
340
+ fetchedAt = 0;
341
+ fetching = null;
342
+ async getKey(kid) {
343
+ if (this.keyMap.size === 0 || Date.now() - this.fetchedAt > CACHE_TTL_MS) {
344
+ await this.fetch();
345
+ }
346
+ let key = this.keyMap.get(kid);
347
+ if (!key) {
348
+ this.logger.debug("jwks.unknown_kid", { kid });
349
+ await this.fetch();
350
+ key = this.keyMap.get(kid);
351
+ }
352
+ if (!key) throw new MiniMothError("INVALID_TOKEN", `No public key found for kid: ${kid}`, 401);
353
+ return key;
354
+ }
355
+ fetch() {
356
+ if (this.fetching) return this.fetching;
357
+ this.fetching = this.doFetch().finally(() => {
358
+ this.fetching = null;
359
+ });
360
+ return this.fetching;
361
+ }
362
+ async doFetch() {
363
+ this.logger.debug("jwks.fetch");
364
+ const data = await apiGet("/.well-known/jwks.json");
365
+ const newMap = /* @__PURE__ */ new Map();
366
+ for (const jwk of data.keys) {
367
+ if (jwk["kid"] && jwk["kty"] === "RSA") {
368
+ const key = import_crypto.default.createPublicKey({ key: jwk, format: "jwk" });
369
+ newMap.set(jwk["kid"], key);
370
+ }
371
+ }
372
+ this.keyMap = newMap;
373
+ this.fetchedAt = Date.now();
374
+ this.logger.debug("jwks.updated", { keyCount: newMap.size });
375
+ }
376
+ };
377
+
378
+ // src/session/RevocationCache.ts
379
+ var MODE_TTL_MS = {
380
+ recheck_1m: 6e4,
381
+ recheck_3m: 18e4
382
+ };
383
+ var EVICTION_TTL_MS = 5 * 60 * 1e3;
384
+ var CLEANUP_WINDOW_MS = 5 * 60 * 1e3;
385
+ var RevocationCache = class {
386
+ constructor(mode, apiKey, logger) {
387
+ this.mode = mode;
388
+ this.apiKey = apiKey;
389
+ this.logger = logger;
390
+ }
391
+ mode;
392
+ apiKey;
393
+ logger;
394
+ cache = /* @__PURE__ */ new Map();
395
+ lastCleanedAt = 0;
396
+ async check(jti, accessToken) {
397
+ if (this.mode === "instant") return true;
398
+ if (this.mode !== "strict") this.maybeCleanup();
399
+ const ttl = MODE_TTL_MS[this.mode] ?? 0;
400
+ if (ttl > 0) {
401
+ const entry = this.cache.get(jti);
402
+ if (entry && Date.now() - entry.checkedAt < ttl) {
403
+ this.logger.debug("revocation.cache.hit", { jti: jti.slice(0, 8) });
404
+ return true;
405
+ }
406
+ }
407
+ try {
408
+ const result = await apiPost(
409
+ "/v1/session/validate",
410
+ this.apiKey,
411
+ { access_token: accessToken }
412
+ );
413
+ if (result.valid && ttl > 0) {
414
+ this.cache.set(jti, { checkedAt: Date.now() });
415
+ }
416
+ return result.valid;
417
+ } catch (err) {
418
+ if (this.mode === "strict") throw err;
419
+ this.logger.warn("revocation.check.failed_open", {
420
+ jti: jti.slice(0, 8),
421
+ error: err instanceof Error ? err.message : "unknown"
422
+ });
423
+ return true;
424
+ }
425
+ }
426
+ maybeCleanup() {
427
+ const now = Date.now();
428
+ if (now - this.lastCleanedAt < CLEANUP_WINDOW_MS) return;
429
+ this.lastCleanedAt = now;
430
+ for (const [jti, entry] of this.cache) {
431
+ if (now - entry.checkedAt > EVICTION_TTL_MS) {
432
+ this.cache.delete(jti);
433
+ }
434
+ }
435
+ }
436
+ };
437
+
438
+ // src/session/RefreshDeduplicator.ts
439
+ var RefreshDeduplicator = class {
440
+ constructor(logger) {
441
+ this.logger = logger;
442
+ }
443
+ logger;
444
+ inflight = /* @__PURE__ */ new Map();
445
+ getOrRun(sessionId, fn) {
446
+ const existing = this.inflight.get(sessionId);
447
+ if (existing) {
448
+ this.logger.debug("refresh dedup hit", { key: sessionId });
449
+ return existing;
450
+ }
451
+ const promise = fn().finally(() => {
452
+ this.inflight.delete(sessionId);
453
+ });
454
+ this.inflight.set(sessionId, promise);
455
+ return promise;
456
+ }
457
+ };
458
+
459
+ // src/store/DefaultSessionStore.ts
460
+ var DefaultSessionStore = class {
461
+ constructor(logger) {
462
+ this.logger = logger;
463
+ }
464
+ logger;
465
+ map = /* @__PURE__ */ new Map();
466
+ warnedProduction = false;
467
+ maybeWarn() {
468
+ if (process.env["NODE_ENV"] === "production" && !this.warnedProduction) {
469
+ this.warnedProduction = true;
470
+ this.logger.warn("using default in-memory session store \u2014 not suitable for multi-replica deployments");
471
+ }
472
+ }
473
+ async getRefreshToken(sessionId) {
474
+ this.maybeWarn();
475
+ return this.map.get(sessionId)?.refreshToken ?? null;
476
+ }
477
+ async setTokens(sessionId, tokens) {
478
+ this.maybeWarn();
479
+ this.map.set(sessionId, tokens);
480
+ }
481
+ async deleteSession(sessionId) {
482
+ this.map.delete(sessionId);
483
+ }
484
+ };
485
+
486
+ // src/logger/ConsoleLogger.ts
487
+ var LEVEL_ORDER = {
488
+ debug: 0,
489
+ info: 1,
490
+ warn: 2,
491
+ error: 3,
492
+ silent: 4
493
+ };
494
+ var ConsoleLogger = class {
495
+ level;
496
+ constructor(level = "info") {
497
+ this.level = level;
498
+ }
499
+ setLevel(level) {
500
+ this.level = level;
501
+ }
502
+ shouldLog(level) {
503
+ return LEVEL_ORDER[level] >= LEVEL_ORDER[this.level];
504
+ }
505
+ format(msg, meta) {
506
+ if (!meta || Object.keys(meta).length === 0) return `[minimoth] ${msg}`;
507
+ return `[minimoth] ${msg} ${JSON.stringify(meta)}`;
508
+ }
509
+ debug(msg, meta) {
510
+ if (this.shouldLog("debug")) console.debug(this.format(msg, meta));
511
+ }
512
+ info(msg, meta) {
513
+ if (this.shouldLog("info")) console.info(this.format(msg, meta));
514
+ }
515
+ warn(msg, meta) {
516
+ if (this.shouldLog("warn")) console.warn(this.format(msg, meta));
517
+ }
518
+ error(msg, meta) {
519
+ if (this.shouldLog("error")) console.error(this.format(msg, meta));
520
+ }
521
+ };
522
+
523
+ // src/MiniMoth.ts
524
+ var MiniMoth = class {
525
+ otp;
526
+ session;
527
+ consoleLogger;
528
+ constructor(config) {
529
+ this.consoleLogger = new ConsoleLogger(config.logLevel ?? "info");
530
+ const logger = config.logger ?? this.consoleLogger;
531
+ const store = config.session?.store ?? new DefaultSessionStore(logger);
532
+ const validateMode = config.session?.validateMode ?? "instant";
533
+ const jwksCache = new JwksCache(logger);
534
+ const revocationCache = new RevocationCache(validateMode, config.apiKey, logger);
535
+ const deduplicator = new RefreshDeduplicator(logger);
536
+ this.otp = new OtpClient(config.apiKey, store, logger);
537
+ this.session = new SessionClient(
538
+ config.apiKey,
539
+ jwksCache,
540
+ revocationCache,
541
+ deduplicator,
542
+ store,
543
+ logger
544
+ );
545
+ }
546
+ // Only affects the built-in ConsoleLogger. Has no effect if a custom logger was provided.
547
+ setLogLevel(level) {
548
+ this.consoleLogger.setLevel(level);
549
+ }
550
+ };
551
+ // Annotate the CommonJS export names for ESM import in node:
552
+ 0 && (module.exports = {
553
+ MiniMoth,
554
+ MiniMothError
555
+ });
556
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../node_modules/tsup/assets/cjs_shims.js","../src/otp/OtpClient.ts","../src/MiniMothError.ts","../src/http.ts","../src/session/SessionClient.ts","../src/session/JwksCache.ts","../src/session/RevocationCache.ts","../src/session/RefreshDeduplicator.ts","../src/store/DefaultSessionStore.ts","../src/logger/ConsoleLogger.ts","../src/MiniMoth.ts"],"sourcesContent":["export { MiniMoth } from './MiniMoth'\nexport { MiniMothError } from './MiniMothError'\nexport type { MiniMothErrorCode } from './MiniMothError'\nexport type { Session, ValidateMode, MiniMothConfig, AccessTokenPayload } from './types'\nexport type { MiniMothSessionStore } from './store/MiniMothSessionStore'\nexport type { MiniMothLogger } from './logger/MiniMothLogger'\n","// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","import jwt from 'jsonwebtoken'\nimport { apiPost } from '../http'\nimport { MiniMothError, type MiniMothErrorCode } from '../MiniMothError'\nimport type { MiniMothSessionStore } from '../store/MiniMothSessionStore'\nimport type { MiniMothLogger } from '../logger/MiniMothLogger'\nimport type { AccessTokenPayload } from '../types'\n\ntype VerifyResult =\n | { valid: true; accessToken: string; refreshToken: string; sessionId: string }\n | { valid: false; code: MiniMothErrorCode }\n\nexport class OtpClient {\n constructor(\n private readonly apiKey: string,\n private readonly store: MiniMothSessionStore,\n private readonly logger: MiniMothLogger\n ) {}\n\n async send(params: { phone: string }): Promise<void> {\n const phone = normalizePhone(params.phone)\n await apiPost<{ message: string }>('/v1/otp/send', this.apiKey, { phone })\n this.logger.info('otp.sent', { phone: maskPhone(phone) })\n }\n\n async verify(params: { phone: string; otp: string }): Promise<VerifyResult> {\n const phone = normalizePhone(params.phone)\n validateOtp(params.otp)\n\n try {\n const res = await apiPost<{ access_token: string; refresh_token: string; expires_at: string }>(\n '/v1/otp/verify',\n this.apiKey,\n { phone, code: params.otp }\n )\n\n const payload = jwt.decode(res.access_token) as AccessTokenPayload | null\n if (!payload?.session_id) {\n throw new MiniMothError('INVALID_TOKEN', 'Could not decode session_id from access token', 0)\n }\n\n try {\n await this.store.setTokens(payload.session_id, {\n accessToken: res.access_token,\n refreshToken: res.refresh_token,\n })\n } catch {\n this.logger.error('otp.store.setTokens.failed', { sessionId: payload.session_id.slice(0, 8) })\n }\n\n this.logger.info('otp.verified', { sessionId: payload.session_id.slice(0, 8) })\n\n return {\n valid: true,\n accessToken: res.access_token,\n refreshToken: res.refresh_token,\n sessionId: payload.session_id,\n }\n } catch (err) {\n if (err instanceof MiniMothError) {\n if (err.code === 'INVALID_OTP' || err.code === 'OTP_EXPIRED' || err.code === 'INVALID_PHONE') {\n this.logger.debug('otp.verify.failed', { code: err.code })\n return { valid: false, code: err.code }\n }\n }\n throw err\n }\n }\n}\n\n// Normalizes to 12-digit canonical Indian format (91XXXXXXXXXX).\n// Rejects if spaces or hyphens are present.\nfunction normalizePhone(raw: string): string {\n if (!raw || typeof raw !== 'string') {\n throw new MiniMothError('INVALID_PHONE', 'Phone number is required', 422)\n }\n if (/[\\s-]/.test(raw)) {\n throw new MiniMothError('INVALID_PHONE', 'Phone number must not contain spaces or hyphens', 422)\n }\n let phone = raw\n if (phone.startsWith('+')) phone = phone.slice(1)\n // 10-digit subscriber number — prepend country code\n if (phone.length === 10) phone = '91' + phone\n return phone\n}\n\nfunction validateOtp(otp: string): void {\n if (!otp || typeof otp !== 'string') {\n throw new MiniMothError('INVALID_OTP', 'OTP is required', 422)\n }\n}\n\nexport function maskPhone(phone: string): string {\n if (phone.length <= 4) return '****'\n return phone.slice(0, 4) + '*'.repeat(Math.max(phone.length - 6, 1)) + phone.slice(-2)\n}\n","export type MiniMothErrorCode =\n | 'TOKEN_EXPIRED'\n | 'TOKEN_REVOKED'\n | 'INVALID_TOKEN'\n | 'INVALID_OTP'\n | 'OTP_EXPIRED'\n | 'RATE_LIMITED'\n | 'INSUFFICIENT_BALANCE'\n | 'NETWORK_ERROR'\n | 'INVALID_PHONE'\n | 'UNKNOWN_ERROR'\n\nexport class MiniMothError extends Error {\n readonly code: MiniMothErrorCode\n readonly statusCode: number\n\n constructor(code: MiniMothErrorCode, message: string, statusCode: number, cause?: unknown) {\n super(message, cause !== undefined ? { cause } : undefined)\n this.name = 'MiniMothError'\n this.code = code\n this.statusCode = statusCode\n // Restore prototype chain for instanceof checks across module boundaries\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n","import { MiniMothError, type MiniMothErrorCode } from './MiniMothError'\nimport { createRequire } from 'module'\n\nconst require = createRequire(import.meta.url)\n// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\nconst pkg = require('../package.json') as { version: string }\n\nconst BASE_URL = 'https://api.minimoth.dev'\nconst USER_AGENT = `minimoth-sdk-node/${pkg.version}`\n\nconst BACKEND_CODE_MAP: Record<string, MiniMothErrorCode> = {\n INVALID_ACCESS_TOKEN: 'INVALID_TOKEN',\n TOKEN_EXPIRED: 'TOKEN_EXPIRED',\n TOKEN_REVOKED: 'TOKEN_REVOKED',\n INVALID_OTP: 'INVALID_OTP',\n OTP_NOT_FOUND: 'OTP_EXPIRED',\n OTP_RATE_LIMITED: 'RATE_LIMITED',\n VERIFY_RATE_LIMITED: 'RATE_LIMITED',\n INSUFFICIENT_BALANCE: 'INSUFFICIENT_BALANCE',\n INVALID_PHONE: 'INVALID_PHONE',\n}\n\nasync function handleResponse<T>(response: Response): Promise<T> {\n if (response.ok) return response.json() as Promise<T>\n\n let body: { code?: string; error?: string } = {}\n try { body = await response.json() as { code?: string; error?: string } } catch {}\n\n const sdkCode: MiniMothErrorCode = BACKEND_CODE_MAP[body.code ?? ''] ?? 'UNKNOWN_ERROR'\n throw new MiniMothError(sdkCode, body.error ?? 'Unknown error', response.status)\n}\n\nexport async function apiPost<T>(\n path: string,\n apiKey: string,\n body: Record<string, unknown>\n): Promise<T> {\n let response: Response\n try {\n response = await fetch(`${BASE_URL}${path}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Api-Key': apiKey,\n 'User-Agent': USER_AGENT,\n },\n body: JSON.stringify(body),\n })\n } catch (err) {\n throw new MiniMothError('NETWORK_ERROR', 'Network request failed', 0, err)\n }\n return handleResponse<T>(response)\n}\n\nexport async function apiGet<T>(path: string): Promise<T> {\n let response: Response\n try {\n response = await fetch(`${BASE_URL}${path}`, {\n headers: { 'User-Agent': USER_AGENT },\n })\n } catch (err) {\n throw new MiniMothError('NETWORK_ERROR', 'Network request failed', 0, err)\n }\n return handleResponse<T>(response)\n}\n","import jwt from 'jsonwebtoken'\nimport { apiPost } from '../http'\nimport { MiniMothError, type MiniMothErrorCode } from '../MiniMothError'\nimport type { JwksCache } from './JwksCache'\nimport type { RevocationCache } from './RevocationCache'\nimport type { RefreshDeduplicator } from './RefreshDeduplicator'\nimport type { MiniMothSessionStore } from '../store/MiniMothSessionStore'\nimport type { MiniMothLogger } from '../logger/MiniMothLogger'\nimport type { Session, AccessTokenPayload } from '../types'\n\ntype Tokens = { accessToken: string; refreshToken: string }\n\ntype SafeValidateResult =\n | { valid: true; session: Session }\n | { valid: false; code: MiniMothErrorCode }\n\nexport class SessionClient {\n constructor(\n private readonly apiKey: string,\n private readonly jwksCache: JwksCache,\n private readonly revocationCache: RevocationCache,\n private readonly deduplicator: RefreshDeduplicator,\n private readonly store: MiniMothSessionStore,\n private readonly logger: MiniMothLogger\n ) {}\n\n async validate(accessToken: string): Promise<Session> {\n const decoded = jwt.decode(accessToken, { complete: true })\n if (!decoded || typeof decoded === 'string') {\n throw new MiniMothError('INVALID_TOKEN', 'Token is malformed', 401)\n }\n\n const kid = (decoded.header as unknown as Record<string, string>)['kid']\n if (!kid) throw new MiniMothError('INVALID_TOKEN', 'Token is missing kid header', 401)\n\n const publicKey = await this.jwksCache.getKey(kid)\n\n let currentToken = accessToken\n let newTokens: Tokens | undefined\n\n try {\n jwt.verify(accessToken, publicKey, { algorithms: ['RS256'] })\n } catch (err) {\n if (err instanceof jwt.TokenExpiredError) {\n const expiredPayload = decoded.payload as AccessTokenPayload\n const sessionId = expiredPayload?.session_id\n if (!sessionId) throw new MiniMothError('INVALID_TOKEN', 'Token is invalid', 401)\n\n newTokens = await this.deduplicator.getOrRun(sessionId, async () => {\n const refreshToken = await this.store.getRefreshToken(sessionId)\n if (!refreshToken) {\n throw new MiniMothError('TOKEN_EXPIRED', 'Access token expired and no refresh token available', 401)\n }\n\n this.logger.info('session.auto_refresh', { sessionId: sessionId.slice(0, 8) })\n const res = await apiPost<{ access_token: string; refresh_token: string }>(\n '/v1/session/refresh',\n this.apiKey,\n { refresh_token: refreshToken }\n )\n\n try {\n await this.store.setTokens(sessionId, {\n accessToken: res.access_token,\n refreshToken: res.refresh_token,\n })\n } catch (err) {\n this.logger.error('session.store.setTokens.failed', { sessionId: sessionId.slice(0, 8) })\n }\n\n return { accessToken: res.access_token, refreshToken: res.refresh_token }\n })\n\n currentToken = newTokens.accessToken\n\n // Verify the new token\n const newDecoded = jwt.decode(currentToken, { complete: true })\n const newKid = (newDecoded?.header as Record<string, string> | undefined)?.['kid']\n const newKey = newKid ? await this.jwksCache.getKey(newKid) : publicKey\n jwt.verify(currentToken, newKey, { algorithms: ['RS256'] })\n } else {\n throw new MiniMothError('INVALID_TOKEN', 'Token signature is invalid', 401)\n }\n }\n\n const payload = jwt.decode(currentToken) as AccessTokenPayload\n const isValid = await this.revocationCache.check(payload.jti, currentToken)\n if (!isValid) throw new MiniMothError('TOKEN_REVOKED', 'Session has been revoked', 401)\n\n const session: Session = {\n phone: payload.sub,\n projectId: payload.project_id,\n sessionId: payload.session_id,\n expiresAt: new Date(payload.exp * 1000),\n }\n if (newTokens) session.newTokens = newTokens\n\n this.logger.info('session.validated', { sessionId: payload.session_id.slice(0, 8) })\n return session\n }\n\n async safeValidate(accessToken: string): Promise<SafeValidateResult> {\n try {\n const session = await this.validate(accessToken)\n return { valid: true, session }\n } catch (err) {\n if (err instanceof MiniMothError) return { valid: false, code: err.code }\n throw err\n }\n }\n\n async refresh(refreshToken: string): Promise<Tokens> {\n const res = await apiPost<{ access_token: string; refresh_token: string }>(\n '/v1/session/refresh',\n this.apiKey,\n { refresh_token: refreshToken }\n )\n\n // Update store if session_id is decodable from new token\n const payload = jwt.decode(res.access_token) as AccessTokenPayload | null\n if (payload?.session_id) {\n try {\n await this.store.setTokens(payload.session_id, {\n accessToken: res.access_token,\n refreshToken: res.refresh_token,\n })\n } catch (err) {\n this.logger.error('session.store.setTokens.failed', { sessionId: payload.session_id.slice(0, 8) })\n }\n }\n\n this.logger.info('session.refreshed')\n return { accessToken: res.access_token, refreshToken: res.refresh_token }\n }\n\n async logout(params: { accessToken: string; refreshToken: string }): Promise<void> {\n const payload = jwt.decode(params.accessToken) as AccessTokenPayload | null\n const sessionId = payload?.session_id ?? null\n\n if (!sessionId) throw new MiniMothError('INVALID_TOKEN', 'Cannot decode token', 401)\n\n let currentAccessToken = params.accessToken\n\n // If token is expired, refresh before logout — deduplicated to prevent concurrent refresh races\n if (payload && payload.exp < Math.floor(Date.now() / 1000)) {\n const newTokens = await this.deduplicator.getOrRun(sessionId, async () => {\n const res = await apiPost<{ access_token: string; refresh_token: string }>(\n '/v1/session/refresh',\n this.apiKey,\n { refresh_token: params.refreshToken }\n )\n return { accessToken: res.access_token, refreshToken: res.refresh_token }\n })\n currentAccessToken = newTokens.accessToken\n try {\n await this.store.setTokens(sessionId, newTokens)\n } catch (err) {\n this.logger.error('session.store.setTokens.failed', { sessionId: sessionId.slice(0, 8) })\n }\n }\n\n await apiPost<{ message: string }>(\n '/v1/session/logout',\n this.apiKey,\n { access_token: currentAccessToken }\n )\n\n try {\n await this.store.deleteSession(sessionId)\n } catch (err) {\n this.logger.error('session.store.deleteSession.failed', { sessionId: sessionId.slice(0, 8) })\n }\n this.logger.info('session.logged_out', { sessionId: sessionId.slice(0, 8) })\n }\n}\n","import crypto from 'crypto'\nimport { apiGet } from '../http'\nimport { MiniMothError } from '../MiniMothError'\nimport type { MiniMothLogger } from '../logger/MiniMothLogger'\n\nconst CACHE_TTL_MS = 60 * 60 * 1000 // 1 hour\n\ntype JwkEntry = Record<string, string>\n\nexport class JwksCache {\n private keyMap = new Map<string, crypto.KeyObject>()\n private fetchedAt = 0\n private fetching: Promise<void> | null = null\n\n constructor(private readonly logger: MiniMothLogger) {}\n\n async getKey(kid: string): Promise<crypto.KeyObject> {\n if (this.keyMap.size === 0 || Date.now() - this.fetchedAt > CACHE_TTL_MS) {\n await this.fetch()\n }\n\n let key = this.keyMap.get(kid)\n if (!key) {\n this.logger.debug('jwks.unknown_kid', { kid })\n await this.fetch()\n key = this.keyMap.get(kid)\n }\n\n if (!key) throw new MiniMothError('INVALID_TOKEN', `No public key found for kid: ${kid}`, 401)\n return key\n }\n\n private fetch(): Promise<void> {\n if (this.fetching) return this.fetching\n this.fetching = this.doFetch().finally(() => { this.fetching = null })\n return this.fetching\n }\n\n private async doFetch(): Promise<void> {\n this.logger.debug('jwks.fetch')\n const data = await apiGet<{ keys: JwkEntry[] }>('/.well-known/jwks.json')\n const newMap = new Map<string, crypto.KeyObject>()\n for (const jwk of data.keys) {\n if (jwk['kid'] && jwk['kty'] === 'RSA') {\n const key = crypto.createPublicKey({ key: jwk as unknown as crypto.JsonWebKey, format: 'jwk' })\n newMap.set(jwk['kid'], key)\n }\n }\n this.keyMap = newMap\n this.fetchedAt = Date.now()\n this.logger.debug('jwks.updated', { keyCount: newMap.size })\n }\n}\n","import { apiPost } from '../http'\nimport type { MiniMothLogger } from '../logger/MiniMothLogger'\nimport type { ValidateMode } from '../types'\n\nconst MODE_TTL_MS: Partial<Record<ValidateMode, number>> = {\n recheck_1m: 60_000,\n recheck_3m: 180_000,\n}\n\nconst EVICTION_TTL_MS = 5 * 60 * 1000 // JWT max lifetime\nconst CLEANUP_WINDOW_MS = 5 * 60 * 1000\n\ntype Entry = { checkedAt: number }\n\nexport class RevocationCache {\n private readonly cache = new Map<string, Entry>()\n private lastCleanedAt = 0\n\n constructor(\n private readonly mode: ValidateMode,\n private readonly apiKey: string,\n private readonly logger: MiniMothLogger\n ) {}\n\n async check(jti: string, accessToken: string): Promise<boolean> {\n if (this.mode === 'instant') return true\n\n if (this.mode !== 'strict') this.maybeCleanup()\n\n const ttl = MODE_TTL_MS[this.mode] ?? 0\n if (ttl > 0) {\n const entry = this.cache.get(jti)\n if (entry && Date.now() - entry.checkedAt < ttl) {\n this.logger.debug('revocation.cache.hit', { jti: jti.slice(0, 8) })\n return true\n }\n }\n\n try {\n const result = await apiPost<{ valid: boolean }>(\n '/v1/session/validate',\n this.apiKey,\n { access_token: accessToken }\n )\n\n if (result.valid && ttl > 0) {\n this.cache.set(jti, { checkedAt: Date.now() })\n }\n\n return result.valid\n } catch (err) {\n if (this.mode === 'strict') throw err\n\n // recheck_*m: fail open\n this.logger.warn('revocation.check.failed_open', {\n jti: jti.slice(0, 8),\n error: err instanceof Error ? err.message : 'unknown',\n })\n return true\n }\n }\n\n private maybeCleanup(): void {\n const now = Date.now()\n if (now - this.lastCleanedAt < CLEANUP_WINDOW_MS) return\n this.lastCleanedAt = now // set before iteration to prevent concurrent double-clean\n for (const [jti, entry] of this.cache) {\n if (now - entry.checkedAt > EVICTION_TTL_MS) {\n this.cache.delete(jti)\n }\n }\n }\n}\n","import { MiniMothLogger } from '../logger/MiniMothLogger'\n\ntype Tokens = { accessToken: string; refreshToken: string }\n\nexport class RefreshDeduplicator {\n private readonly inflight = new Map<string, Promise<unknown>>()\n\n constructor(private readonly logger: MiniMothLogger) {}\n\n getOrRun<T>(sessionId: string, fn: () => Promise<T>): Promise<T> {\n const existing = this.inflight.get(sessionId)\n if (existing) {\n this.logger.debug('refresh dedup hit', { key: sessionId })\n return existing as Promise<T>\n }\n\n const promise = fn().finally(() => {\n this.inflight.delete(sessionId)\n })\n\n this.inflight.set(sessionId, promise)\n return promise\n }\n}\n","import type { MiniMothSessionStore } from './MiniMothSessionStore'\nimport type { MiniMothLogger } from '../logger/MiniMothLogger'\n\ntype Entry = { accessToken: string; refreshToken: string }\n\nexport class DefaultSessionStore implements MiniMothSessionStore {\n private readonly map = new Map<string, Entry>()\n private warnedProduction = false\n\n constructor(private readonly logger: MiniMothLogger) {}\n\n private maybeWarn(): void {\n if (process.env['NODE_ENV'] === 'production' && !this.warnedProduction) {\n this.warnedProduction = true\n this.logger.warn('using default in-memory session store — not suitable for multi-replica deployments')\n }\n }\n\n async getRefreshToken(sessionId: string): Promise<string | null> {\n this.maybeWarn()\n return this.map.get(sessionId)?.refreshToken ?? null\n }\n\n async setTokens(sessionId: string, tokens: { accessToken: string; refreshToken: string }): Promise<void> {\n this.maybeWarn()\n this.map.set(sessionId, tokens)\n }\n\n async deleteSession(sessionId: string): Promise<void> {\n this.map.delete(sessionId)\n }\n}\n","import type { MiniMothLogger } from './MiniMothLogger'\n\ntype LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent'\n\nconst LEVEL_ORDER: Record<LogLevel, number> = {\n debug: 0, info: 1, warn: 2, error: 3, silent: 4,\n}\n\nexport class ConsoleLogger implements MiniMothLogger {\n private level: LogLevel\n\n constructor(level: LogLevel = 'info') {\n this.level = level\n }\n\n setLevel(level: LogLevel): void {\n this.level = level\n }\n\n private shouldLog(level: LogLevel): boolean {\n return LEVEL_ORDER[level] >= LEVEL_ORDER[this.level]\n }\n\n private format(msg: string, meta?: Record<string, unknown>): string {\n if (!meta || Object.keys(meta).length === 0) return `[minimoth] ${msg}`\n return `[minimoth] ${msg} ${JSON.stringify(meta)}`\n }\n\n debug(msg: string, meta?: Record<string, unknown>): void {\n if (this.shouldLog('debug')) console.debug(this.format(msg, meta))\n }\n\n info(msg: string, meta?: Record<string, unknown>): void {\n if (this.shouldLog('info')) console.info(this.format(msg, meta))\n }\n\n warn(msg: string, meta?: Record<string, unknown>): void {\n if (this.shouldLog('warn')) console.warn(this.format(msg, meta))\n }\n\n error(msg: string, meta?: Record<string, unknown>): void {\n if (this.shouldLog('error')) console.error(this.format(msg, meta))\n }\n}\n","import { OtpClient } from './otp/OtpClient'\nimport { SessionClient } from './session/SessionClient'\nimport { JwksCache } from './session/JwksCache'\nimport { RevocationCache } from './session/RevocationCache'\nimport { RefreshDeduplicator } from './session/RefreshDeduplicator'\nimport { DefaultSessionStore } from './store/DefaultSessionStore'\nimport { ConsoleLogger } from './logger/ConsoleLogger'\nimport type { MiniMothConfig } from './types'\n\ntype LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent'\n\nexport class MiniMoth {\n readonly otp: OtpClient\n readonly session: SessionClient\n private readonly consoleLogger: ConsoleLogger\n\n constructor(config: MiniMothConfig) {\n this.consoleLogger = new ConsoleLogger(config.logLevel ?? 'info')\n const logger = config.logger ?? this.consoleLogger\n\n const store = config.session?.store ?? new DefaultSessionStore(logger)\n const validateMode = config.session?.validateMode ?? 'instant'\n\n const jwksCache = new JwksCache(logger)\n const revocationCache = new RevocationCache(validateMode, config.apiKey, logger)\n const deduplicator = new RefreshDeduplicator(logger)\n\n this.otp = new OtpClient(config.apiKey, store, logger)\n this.session = new SessionClient(\n config.apiKey,\n jwksCache,\n revocationCache,\n deduplicator,\n store,\n logger\n )\n }\n\n // Only affects the built-in ConsoleLogger. Has no effect if a custom logger was provided.\n setLogLevel(level: LogLevel): void {\n this.consoleLogger.setLevel(level)\n }\n}\n"],"mappings":"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","names":["require","jwt","import_jsonwebtoken","jwt","err","crypto"]}