emulate 0.5.0 → 0.6.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 +141 -19
- package/dist/api.js +460 -24
- package/dist/api.js.map +1 -1
- package/dist/{dist-PWGOAQC6.js → dist-2ZZGNPJI.js} +1 -1
- package/dist/dist-2ZZGNPJI.js.map +1 -0
- package/dist/{dist-4X2KPMAJ.js → dist-CXRPM6BK.js} +1 -3
- package/dist/dist-CXRPM6BK.js.map +1 -0
- package/dist/{dist-LDUHEJAN.js → dist-DSJSF3GY.js} +1 -3
- package/dist/dist-DSJSF3GY.js.map +1 -0
- package/dist/{dist-ETHHYBGF.js → dist-IFULY5LE.js} +1 -2
- package/dist/dist-IFULY5LE.js.map +1 -0
- package/dist/{dist-J6LHUR52.js → dist-IRUBHCZU.js} +1 -2
- package/dist/dist-IRUBHCZU.js.map +1 -0
- package/dist/{dist-ENKE2S7V.js → dist-NJJLJT2N.js} +1 -3
- package/dist/dist-NJJLJT2N.js.map +1 -0
- package/dist/dist-OGSAVJ25.js +4874 -0
- package/dist/dist-OGSAVJ25.js.map +1 -0
- package/dist/{dist-REDHDZ3V.js → dist-PO4CL5SJ.js} +1 -3
- package/dist/dist-PO4CL5SJ.js.map +1 -0
- package/dist/{dist-IBXD3O6A.js → dist-R3TNKUIE.js} +1 -3
- package/dist/dist-R3TNKUIE.js.map +1 -0
- package/dist/{dist-CFST4X4K.js → dist-WACHAAVU.js} +1 -2
- package/dist/dist-WACHAAVU.js.map +1 -0
- package/dist/{dist-5JVGPOL3.js → dist-XWWZVLQQ.js} +1 -2
- package/dist/dist-XWWZVLQQ.js.map +1 -0
- package/dist/{dist-KKTYBE5S.js → dist-ZY5SZSJ2.js} +8 -3
- package/dist/dist-ZY5SZSJ2.js.map +1 -0
- package/dist/index.js +464 -26
- package/dist/index.js.map +1 -1
- package/package.json +14 -15
- package/dist/chunk-AQ2CLRU3.js +0 -2146
- package/dist/chunk-AQ2CLRU3.js.map +0 -1
- package/dist/dist-4X2KPMAJ.js.map +0 -1
- package/dist/dist-5JVGPOL3.js.map +0 -1
- package/dist/dist-CE6BUCWQ.js +0 -1438
- package/dist/dist-CE6BUCWQ.js.map +0 -1
- package/dist/dist-CFST4X4K.js.map +0 -1
- package/dist/dist-ENKE2S7V.js.map +0 -1
- package/dist/dist-ETHHYBGF.js.map +0 -1
- package/dist/dist-IBXD3O6A.js.map +0 -1
- package/dist/dist-J6LHUR52.js.map +0 -1
- package/dist/dist-KKTYBE5S.js.map +0 -1
- package/dist/dist-LDUHEJAN.js.map +0 -1
- package/dist/dist-PWGOAQC6.js.map +0 -1
- package/dist/dist-REDHDZ3V.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -3,15 +3,12 @@ import {
|
|
|
3
3
|
importPKCS8,
|
|
4
4
|
jwtVerify
|
|
5
5
|
} from "./chunk-D6EKRYGP.js";
|
|
6
|
-
import {
|
|
7
|
-
Hono,
|
|
8
|
-
cors
|
|
9
|
-
} from "./chunk-AQ2CLRU3.js";
|
|
10
6
|
|
|
11
7
|
// src/index.ts
|
|
12
8
|
import { Command } from "commander";
|
|
13
9
|
|
|
14
10
|
// ../@emulators/core/dist/index.js
|
|
11
|
+
import { createServer as createNodeServer } from "http";
|
|
15
12
|
import { createHmac } from "crypto";
|
|
16
13
|
import { readFileSync } from "fs";
|
|
17
14
|
import { fileURLToPath } from "url";
|
|
@@ -235,6 +232,397 @@ var Store = class {
|
|
|
235
232
|
}
|
|
236
233
|
}
|
|
237
234
|
};
|
|
235
|
+
var HonoRequest = class {
|
|
236
|
+
constructor(request, params) {
|
|
237
|
+
this.params = params;
|
|
238
|
+
this.raw = request;
|
|
239
|
+
this.url = request.url;
|
|
240
|
+
this.method = request.method;
|
|
241
|
+
this.path = new URL(request.url).pathname;
|
|
242
|
+
}
|
|
243
|
+
raw;
|
|
244
|
+
url;
|
|
245
|
+
method;
|
|
246
|
+
path;
|
|
247
|
+
header(name) {
|
|
248
|
+
if (name) return this.raw.headers.get(name) ?? void 0;
|
|
249
|
+
const headers = {};
|
|
250
|
+
this.raw.headers.forEach((value, key) => {
|
|
251
|
+
headers[key] = value;
|
|
252
|
+
});
|
|
253
|
+
return headers;
|
|
254
|
+
}
|
|
255
|
+
query(name) {
|
|
256
|
+
return new URL(this.url).searchParams.get(name) ?? void 0;
|
|
257
|
+
}
|
|
258
|
+
queries(name) {
|
|
259
|
+
const values = new URL(this.url).searchParams.getAll(name);
|
|
260
|
+
return values.length > 0 ? values : void 0;
|
|
261
|
+
}
|
|
262
|
+
param(name) {
|
|
263
|
+
if (!name) return { ...this.params };
|
|
264
|
+
return this.params[name] ?? "";
|
|
265
|
+
}
|
|
266
|
+
json() {
|
|
267
|
+
return this.raw.json();
|
|
268
|
+
}
|
|
269
|
+
text() {
|
|
270
|
+
return this.raw.text();
|
|
271
|
+
}
|
|
272
|
+
arrayBuffer() {
|
|
273
|
+
return this.raw.arrayBuffer();
|
|
274
|
+
}
|
|
275
|
+
async parseBody() {
|
|
276
|
+
const contentType = this.header("Content-Type") ?? "";
|
|
277
|
+
if (contentType.includes("multipart/form-data")) {
|
|
278
|
+
return formDataToObject(await this.raw.formData());
|
|
279
|
+
}
|
|
280
|
+
if (contentType.includes("application/x-www-form-urlencoded")) {
|
|
281
|
+
const params = new URLSearchParams(await this.raw.text());
|
|
282
|
+
const out = {};
|
|
283
|
+
for (const [key, value] of params) {
|
|
284
|
+
appendBodyValue(out, key, value);
|
|
285
|
+
}
|
|
286
|
+
return out;
|
|
287
|
+
}
|
|
288
|
+
if (contentType.includes("application/json")) {
|
|
289
|
+
const body = await this.raw.json().catch(() => ({}));
|
|
290
|
+
return body && typeof body === "object" && !Array.isArray(body) ? body : {};
|
|
291
|
+
}
|
|
292
|
+
return {};
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
var Context = class {
|
|
296
|
+
constructor(request, params, notFoundHandler) {
|
|
297
|
+
this.notFoundHandler = notFoundHandler;
|
|
298
|
+
this.req = new HonoRequest(request, params);
|
|
299
|
+
}
|
|
300
|
+
req;
|
|
301
|
+
vars = /* @__PURE__ */ new Map();
|
|
302
|
+
responseHeaders = new Headers();
|
|
303
|
+
responseStatus = 200;
|
|
304
|
+
get(key) {
|
|
305
|
+
return this.vars.get(key);
|
|
306
|
+
}
|
|
307
|
+
set(key, value) {
|
|
308
|
+
this.vars.set(key, value);
|
|
309
|
+
}
|
|
310
|
+
header(name, value) {
|
|
311
|
+
this.responseHeaders.set(name, value);
|
|
312
|
+
}
|
|
313
|
+
status(status) {
|
|
314
|
+
this.responseStatus = status;
|
|
315
|
+
}
|
|
316
|
+
json(data, status, headers) {
|
|
317
|
+
return this.response(JSON.stringify(data), status, defaultContentType(headers, "application/json; charset=UTF-8"));
|
|
318
|
+
}
|
|
319
|
+
text(text, status, headers) {
|
|
320
|
+
return this.response(text, status, defaultContentType(headers, "text/plain; charset=UTF-8"));
|
|
321
|
+
}
|
|
322
|
+
html(html, status, headers) {
|
|
323
|
+
return this.response(html, status, defaultContentType(headers, "text/html; charset=UTF-8"));
|
|
324
|
+
}
|
|
325
|
+
body(body, status, headers) {
|
|
326
|
+
return this.response(body, status, headers);
|
|
327
|
+
}
|
|
328
|
+
redirect(location, status = 302) {
|
|
329
|
+
return this.response(null, status, { Location: location });
|
|
330
|
+
}
|
|
331
|
+
notFound() {
|
|
332
|
+
return this.notFoundHandler(this);
|
|
333
|
+
}
|
|
334
|
+
finalize(response) {
|
|
335
|
+
if (!hasHeaders(this.responseHeaders)) return response;
|
|
336
|
+
const headers = new Headers(response.headers);
|
|
337
|
+
this.responseHeaders.forEach((value, key) => {
|
|
338
|
+
headers.set(key, value);
|
|
339
|
+
});
|
|
340
|
+
return new Response(response.body, {
|
|
341
|
+
status: response.status,
|
|
342
|
+
statusText: response.statusText,
|
|
343
|
+
headers
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
response(body, status, headers) {
|
|
347
|
+
const merged = new Headers(headers);
|
|
348
|
+
this.responseHeaders.forEach((value, key) => {
|
|
349
|
+
merged.set(key, value);
|
|
350
|
+
});
|
|
351
|
+
return new Response(body, {
|
|
352
|
+
status: status ?? this.responseStatus,
|
|
353
|
+
headers: merged
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
};
|
|
357
|
+
var Hono = class {
|
|
358
|
+
middleware = [];
|
|
359
|
+
routes = [];
|
|
360
|
+
errorHandler = (err) => {
|
|
361
|
+
const message = err instanceof Error ? err.message : "Internal Server Error";
|
|
362
|
+
return new Response(message, { status: 500 });
|
|
363
|
+
};
|
|
364
|
+
notFoundHandler = () => new Response("404 Not Found", { status: 404 });
|
|
365
|
+
use(pathOrHandler, ...handlers) {
|
|
366
|
+
if (typeof pathOrHandler === "string") {
|
|
367
|
+
this.middleware.push({ method: "ALL", compiled: compilePath(pathOrHandler), handlers });
|
|
368
|
+
} else {
|
|
369
|
+
this.middleware.push({ method: "ALL", compiled: compilePath("*"), handlers: [pathOrHandler, ...handlers] });
|
|
370
|
+
}
|
|
371
|
+
return this;
|
|
372
|
+
}
|
|
373
|
+
on(method, path, ...handlers) {
|
|
374
|
+
this.routes.push({ method: method.toUpperCase(), compiled: compilePath(path), handlers });
|
|
375
|
+
return this;
|
|
376
|
+
}
|
|
377
|
+
get(path, ...handlers) {
|
|
378
|
+
return this.on("GET", path, ...handlers);
|
|
379
|
+
}
|
|
380
|
+
post(path, ...handlers) {
|
|
381
|
+
return this.on("POST", path, ...handlers);
|
|
382
|
+
}
|
|
383
|
+
put(path, ...handlers) {
|
|
384
|
+
return this.on("PUT", path, ...handlers);
|
|
385
|
+
}
|
|
386
|
+
patch(path, ...handlers) {
|
|
387
|
+
return this.on("PATCH", path, ...handlers);
|
|
388
|
+
}
|
|
389
|
+
delete(path, ...handlers) {
|
|
390
|
+
return this.on("DELETE", path, ...handlers);
|
|
391
|
+
}
|
|
392
|
+
onError(handler) {
|
|
393
|
+
this.errorHandler = handler;
|
|
394
|
+
return this;
|
|
395
|
+
}
|
|
396
|
+
notFound(handler) {
|
|
397
|
+
this.notFoundHandler = handler;
|
|
398
|
+
return this;
|
|
399
|
+
}
|
|
400
|
+
async request(input, init) {
|
|
401
|
+
if (input instanceof Request) return this.fetch(input);
|
|
402
|
+
const url = input.startsWith("/") ? `http://localhost${input}` : input;
|
|
403
|
+
return this.fetch(new Request(url, init));
|
|
404
|
+
}
|
|
405
|
+
fetch = async (request) => {
|
|
406
|
+
const url = new URL(request.url);
|
|
407
|
+
const path = url.pathname;
|
|
408
|
+
const method = request.method.toUpperCase();
|
|
409
|
+
const matched = this.match(method, path);
|
|
410
|
+
const context = new Context(request, matched.params, this.notFoundHandler);
|
|
411
|
+
try {
|
|
412
|
+
const response = await this.dispatch(context, matched.handlers);
|
|
413
|
+
return context.finalize(response ?? await this.notFoundHandler(context));
|
|
414
|
+
} catch (err) {
|
|
415
|
+
return context.finalize(await this.errorHandler(err, context));
|
|
416
|
+
}
|
|
417
|
+
};
|
|
418
|
+
match(method, path) {
|
|
419
|
+
const handlers = [];
|
|
420
|
+
const params = {};
|
|
421
|
+
for (const route2 of this.middleware) {
|
|
422
|
+
const match = matchPath(route2.compiled, path);
|
|
423
|
+
if (!match) continue;
|
|
424
|
+
Object.assign(params, match);
|
|
425
|
+
for (const handler of route2.handlers) {
|
|
426
|
+
handlers.push({ handler, params: match });
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
const route = this.routes.find((candidate) => candidate.method === method && matchPath(candidate.compiled, path) != null) ?? (method === "HEAD" ? this.routes.find((candidate) => candidate.method === "GET" && matchPath(candidate.compiled, path) != null) : void 0);
|
|
430
|
+
if (route) {
|
|
431
|
+
const match = matchPath(route.compiled, path) ?? {};
|
|
432
|
+
Object.assign(params, match);
|
|
433
|
+
for (const handler of route.handlers) {
|
|
434
|
+
handlers.push({ handler, params: match });
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
return { handlers, params };
|
|
438
|
+
}
|
|
439
|
+
async dispatch(context, handlers) {
|
|
440
|
+
let index = -1;
|
|
441
|
+
const run = async (nextIndex) => {
|
|
442
|
+
if (nextIndex <= index) throw new Error("next() called multiple times");
|
|
443
|
+
index = nextIndex;
|
|
444
|
+
const matched = handlers[nextIndex];
|
|
445
|
+
if (!matched) return void 0;
|
|
446
|
+
const originalParams = context.req.param();
|
|
447
|
+
Object.assign(originalParams, matched.params);
|
|
448
|
+
let nextResponse = void 0;
|
|
449
|
+
let nextCalled = false;
|
|
450
|
+
const next = async () => {
|
|
451
|
+
nextCalled = true;
|
|
452
|
+
nextResponse = await run(nextIndex + 1);
|
|
453
|
+
};
|
|
454
|
+
const response = await matched.handler(context, next);
|
|
455
|
+
if (response instanceof Response) return response;
|
|
456
|
+
if (nextCalled) return nextResponse;
|
|
457
|
+
return response;
|
|
458
|
+
};
|
|
459
|
+
return run(0);
|
|
460
|
+
}
|
|
461
|
+
};
|
|
462
|
+
function cors(options = {}) {
|
|
463
|
+
const origin = options.origin ?? "*";
|
|
464
|
+
const allowMethods = options.allowMethods ?? ["GET", "HEAD", "PUT", "POST", "DELETE", "PATCH", "OPTIONS"];
|
|
465
|
+
return async (c, next) => {
|
|
466
|
+
c.header("Access-Control-Allow-Origin", origin);
|
|
467
|
+
if (options.credentials) c.header("Access-Control-Allow-Credentials", "true");
|
|
468
|
+
if (c.req.method.toUpperCase() === "OPTIONS") {
|
|
469
|
+
c.header("Access-Control-Allow-Methods", allowMethods.join(","));
|
|
470
|
+
const allowHeaders = options.allowHeaders?.join(",") ?? c.req.header("Access-Control-Request-Headers");
|
|
471
|
+
if (allowHeaders) c.header("Access-Control-Allow-Headers", allowHeaders);
|
|
472
|
+
if (options.maxAge != null) c.header("Access-Control-Max-Age", String(options.maxAge));
|
|
473
|
+
return c.body(null, 204);
|
|
474
|
+
}
|
|
475
|
+
await next();
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
function serve(options) {
|
|
479
|
+
const port = options.port ?? 3e3;
|
|
480
|
+
const server = createNodeServer(async (req, res) => {
|
|
481
|
+
try {
|
|
482
|
+
const request = nodeRequestToFetchRequest(req);
|
|
483
|
+
const response = await options.fetch(request);
|
|
484
|
+
await writeFetchResponse(res, response, req.method?.toUpperCase() === "HEAD");
|
|
485
|
+
} catch (err) {
|
|
486
|
+
const message = err instanceof Error ? err.message : "Internal Server Error";
|
|
487
|
+
res.statusCode = 500;
|
|
488
|
+
res.setHeader("Content-Type", "text/plain; charset=UTF-8");
|
|
489
|
+
res.end(message);
|
|
490
|
+
}
|
|
491
|
+
});
|
|
492
|
+
server.listen(port, options.hostname);
|
|
493
|
+
return server;
|
|
494
|
+
}
|
|
495
|
+
function compilePath(pattern) {
|
|
496
|
+
if (pattern === "*" || pattern === "/*") {
|
|
497
|
+
return { pattern, regex: /^.*$/, paramNames: [] };
|
|
498
|
+
}
|
|
499
|
+
const paramNames = [];
|
|
500
|
+
let source = "^";
|
|
501
|
+
for (let i = 0; i < pattern.length; i++) {
|
|
502
|
+
const char = pattern[i];
|
|
503
|
+
if (char !== ":") {
|
|
504
|
+
source += escapeRegex(char);
|
|
505
|
+
continue;
|
|
506
|
+
}
|
|
507
|
+
let name = "";
|
|
508
|
+
i++;
|
|
509
|
+
while (i < pattern.length && /[A-Za-z0-9_]/.test(pattern[i])) {
|
|
510
|
+
name += pattern[i];
|
|
511
|
+
i++;
|
|
512
|
+
}
|
|
513
|
+
i--;
|
|
514
|
+
paramNames.push(name);
|
|
515
|
+
if (pattern[i + 1] === "{") {
|
|
516
|
+
const close = pattern.indexOf("}", i + 2);
|
|
517
|
+
if (close < 0) throw new Error(`Invalid route pattern: ${pattern}`);
|
|
518
|
+
const expr = pattern.slice(i + 2, close);
|
|
519
|
+
source += `(${expr})`;
|
|
520
|
+
i = close;
|
|
521
|
+
} else {
|
|
522
|
+
source += "([^/]+)";
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
source += "$";
|
|
526
|
+
return { pattern, regex: new RegExp(source), paramNames };
|
|
527
|
+
}
|
|
528
|
+
function matchPath(compiled, path) {
|
|
529
|
+
const match = compiled.regex.exec(path);
|
|
530
|
+
if (!match) return null;
|
|
531
|
+
const params = {};
|
|
532
|
+
for (let i = 0; i < compiled.paramNames.length; i++) {
|
|
533
|
+
params[compiled.paramNames[i]] = decodePathParam(match[i + 1] ?? "");
|
|
534
|
+
}
|
|
535
|
+
return params;
|
|
536
|
+
}
|
|
537
|
+
function decodePathParam(value) {
|
|
538
|
+
try {
|
|
539
|
+
return decodeURIComponent(value);
|
|
540
|
+
} catch {
|
|
541
|
+
return value;
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
function escapeRegex(value) {
|
|
545
|
+
return value.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&");
|
|
546
|
+
}
|
|
547
|
+
function hasHeaders(headers) {
|
|
548
|
+
for (const _ of headers) return true;
|
|
549
|
+
return false;
|
|
550
|
+
}
|
|
551
|
+
function defaultContentType(headers, contentType) {
|
|
552
|
+
const out = new Headers(headers);
|
|
553
|
+
if (!out.has("Content-Type")) {
|
|
554
|
+
out.set("Content-Type", contentType);
|
|
555
|
+
}
|
|
556
|
+
return out;
|
|
557
|
+
}
|
|
558
|
+
function formDataToObject(formData) {
|
|
559
|
+
const out = {};
|
|
560
|
+
for (const [key, value] of formData) {
|
|
561
|
+
appendBodyValue(out, key, value);
|
|
562
|
+
}
|
|
563
|
+
return out;
|
|
564
|
+
}
|
|
565
|
+
function appendBodyValue(target, key, value) {
|
|
566
|
+
const existing = target[key];
|
|
567
|
+
if (existing === void 0) {
|
|
568
|
+
target[key] = value;
|
|
569
|
+
} else if (Array.isArray(existing)) {
|
|
570
|
+
existing.push(value);
|
|
571
|
+
} else {
|
|
572
|
+
target[key] = [existing, value];
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
function nodeRequestToFetchRequest(req) {
|
|
576
|
+
const host = req.headers.host ?? "localhost";
|
|
577
|
+
const url = new URL(req.url ?? "/", `http://${host}`);
|
|
578
|
+
const headers = new Headers();
|
|
579
|
+
for (const [key, value] of Object.entries(req.headers)) {
|
|
580
|
+
if (value == null) continue;
|
|
581
|
+
if (Array.isArray(value)) {
|
|
582
|
+
for (const item of value) headers.append(key, item);
|
|
583
|
+
} else {
|
|
584
|
+
headers.set(key, value);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
const method = req.method ?? "GET";
|
|
588
|
+
const hasBody = method !== "GET" && method !== "HEAD";
|
|
589
|
+
return new Request(url.toString(), {
|
|
590
|
+
method,
|
|
591
|
+
headers,
|
|
592
|
+
body: hasBody ? req : void 0,
|
|
593
|
+
duplex: "half"
|
|
594
|
+
});
|
|
595
|
+
}
|
|
596
|
+
async function writeFetchResponse(res, response, headOnly) {
|
|
597
|
+
res.statusCode = response.status;
|
|
598
|
+
res.statusMessage = response.statusText;
|
|
599
|
+
const headersWithCookies = response.headers;
|
|
600
|
+
const cookies = headersWithCookies.getSetCookie?.();
|
|
601
|
+
response.headers.forEach((value, key) => {
|
|
602
|
+
if (key.toLowerCase() === "set-cookie" && cookies && cookies.length > 0) return;
|
|
603
|
+
res.setHeader(key, value);
|
|
604
|
+
});
|
|
605
|
+
if (cookies && cookies.length > 0) {
|
|
606
|
+
res.setHeader("Set-Cookie", cookies);
|
|
607
|
+
}
|
|
608
|
+
if (headOnly || !response.body) {
|
|
609
|
+
res.end();
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
const reader = response.body.getReader();
|
|
613
|
+
try {
|
|
614
|
+
while (true) {
|
|
615
|
+
const { done, value } = await reader.read();
|
|
616
|
+
if (done) break;
|
|
617
|
+
if (!res.write(value)) {
|
|
618
|
+
await new Promise((resolve3) => res.once("drain", resolve3));
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
res.end();
|
|
622
|
+
} catch (err) {
|
|
623
|
+
res.destroy(err instanceof Error ? err : void 0);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
238
626
|
var MAX_DELIVERIES = 1e3;
|
|
239
627
|
var WebhookDispatcher = class {
|
|
240
628
|
subscriptions = [];
|
|
@@ -539,7 +927,7 @@ var SERVICE_REGISTRY = {
|
|
|
539
927
|
label: "Vercel REST API emulator",
|
|
540
928
|
endpoints: "projects, deployments, domains, env vars, users, teams, file uploads, protection bypass",
|
|
541
929
|
async load() {
|
|
542
|
-
const mod = await import("./dist-
|
|
930
|
+
const mod = await import("./dist-CXRPM6BK.js");
|
|
543
931
|
return { plugin: mod.vercelPlugin, seedFromConfig: mod.seedFromConfig };
|
|
544
932
|
},
|
|
545
933
|
defaultFallback(cfg) {
|
|
@@ -566,7 +954,7 @@ var SERVICE_REGISTRY = {
|
|
|
566
954
|
label: "GitHub REST API emulator",
|
|
567
955
|
endpoints: "users, repos, issues, PRs, comments, reviews, labels, milestones, branches, git data, orgs, teams, releases, webhooks, search, actions, checks, rate limit",
|
|
568
956
|
async load() {
|
|
569
|
-
const mod = await import("./dist-
|
|
957
|
+
const mod = await import("./dist-PO4CL5SJ.js");
|
|
570
958
|
return {
|
|
571
959
|
plugin: mod.githubPlugin,
|
|
572
960
|
seedFromConfig: mod.seedFromConfig,
|
|
@@ -633,7 +1021,7 @@ var SERVICE_REGISTRY = {
|
|
|
633
1021
|
label: "Google OAuth 2.0 / OpenID Connect + Gmail, Calendar, and Drive emulator",
|
|
634
1022
|
endpoints: "OAuth authorize, token exchange, userinfo, OIDC discovery, token revocation, Gmail messages/drafts/threads/labels/history/settings, Calendar lists/events/freebusy, Drive files/uploads",
|
|
635
1023
|
async load() {
|
|
636
|
-
const mod = await import("./dist-
|
|
1024
|
+
const mod = await import("./dist-ZY5SZSJ2.js");
|
|
637
1025
|
return { plugin: mod.googlePlugin, seedFromConfig: mod.seedFromConfig };
|
|
638
1026
|
},
|
|
639
1027
|
defaultFallback(cfg) {
|
|
@@ -713,18 +1101,34 @@ var SERVICE_REGISTRY = {
|
|
|
713
1101
|
},
|
|
714
1102
|
slack: {
|
|
715
1103
|
label: "Slack API emulator",
|
|
716
|
-
endpoints: "auth, chat, conversations, users, reactions, team, OAuth, incoming webhooks",
|
|
1104
|
+
endpoints: "auth, chat, conversations, users, profiles, presence, files, pins, bookmarks, views, reactions, team, OAuth, incoming webhooks, inspector",
|
|
717
1105
|
async load() {
|
|
718
|
-
const mod = await import("./dist-
|
|
1106
|
+
const mod = await import("./dist-OGSAVJ25.js");
|
|
719
1107
|
return { plugin: mod.slackPlugin, seedFromConfig: mod.seedFromConfig };
|
|
720
1108
|
},
|
|
721
1109
|
defaultFallback() {
|
|
722
|
-
return {
|
|
1110
|
+
return {
|
|
1111
|
+
login: "U000000001",
|
|
1112
|
+
id: 1,
|
|
1113
|
+
scopes: []
|
|
1114
|
+
};
|
|
723
1115
|
},
|
|
724
1116
|
initConfig: {
|
|
725
1117
|
slack: {
|
|
726
1118
|
team: { name: "My Workspace", domain: "my-workspace" },
|
|
727
|
-
users: [
|
|
1119
|
+
users: [
|
|
1120
|
+
{
|
|
1121
|
+
name: "developer",
|
|
1122
|
+
real_name: "Developer",
|
|
1123
|
+
email: "dev@example.com",
|
|
1124
|
+
profile: {
|
|
1125
|
+
title: "Local Developer",
|
|
1126
|
+
status_text: "Testing locally",
|
|
1127
|
+
status_emoji: ":computer:"
|
|
1128
|
+
},
|
|
1129
|
+
presence: "active"
|
|
1130
|
+
}
|
|
1131
|
+
],
|
|
728
1132
|
channels: [
|
|
729
1133
|
{ name: "general", topic: "General discussion" },
|
|
730
1134
|
{ name: "random", topic: "Random stuff" }
|
|
@@ -734,10 +1138,45 @@ var SERVICE_REGISTRY = {
|
|
|
734
1138
|
{
|
|
735
1139
|
client_id: "12345.67890",
|
|
736
1140
|
client_secret: "example_client_secret",
|
|
1141
|
+
app_id: "A000000001",
|
|
737
1142
|
name: "My Slack App",
|
|
738
|
-
redirect_uris: ["http://localhost:3000/api/auth/callback/slack"]
|
|
1143
|
+
redirect_uris: ["http://localhost:3000/api/auth/callback/slack"],
|
|
1144
|
+
scopes: [
|
|
1145
|
+
"chat:write",
|
|
1146
|
+
"channels:read",
|
|
1147
|
+
"channels:history",
|
|
1148
|
+
"channels:join",
|
|
1149
|
+
"channels:manage",
|
|
1150
|
+
"channels:write",
|
|
1151
|
+
"groups:read",
|
|
1152
|
+
"groups:history",
|
|
1153
|
+
"groups:write",
|
|
1154
|
+
"im:read",
|
|
1155
|
+
"im:history",
|
|
1156
|
+
"im:write",
|
|
1157
|
+
"mpim:read",
|
|
1158
|
+
"mpim:history",
|
|
1159
|
+
"mpim:write",
|
|
1160
|
+
"users:read",
|
|
1161
|
+
"users:read.email",
|
|
1162
|
+
"users.profile:read",
|
|
1163
|
+
"users.profile:write",
|
|
1164
|
+
"users:write",
|
|
1165
|
+
"files:read",
|
|
1166
|
+
"files:write",
|
|
1167
|
+
"pins:read",
|
|
1168
|
+
"pins:write",
|
|
1169
|
+
"bookmarks:read",
|
|
1170
|
+
"bookmarks:write",
|
|
1171
|
+
"reactions:read",
|
|
1172
|
+
"reactions:write",
|
|
1173
|
+
"team:read"
|
|
1174
|
+
],
|
|
1175
|
+
user_scopes: ["users:read", "users.profile:read"],
|
|
1176
|
+
bot_name: "my-bot"
|
|
739
1177
|
}
|
|
740
|
-
]
|
|
1178
|
+
],
|
|
1179
|
+
strict_scopes: false
|
|
741
1180
|
}
|
|
742
1181
|
}
|
|
743
1182
|
},
|
|
@@ -745,7 +1184,7 @@ var SERVICE_REGISTRY = {
|
|
|
745
1184
|
label: "Apple Sign In / OAuth emulator",
|
|
746
1185
|
endpoints: "OAuth authorize, token exchange, JWKS",
|
|
747
1186
|
async load() {
|
|
748
|
-
const mod = await import("./dist-
|
|
1187
|
+
const mod = await import("./dist-WACHAAVU.js");
|
|
749
1188
|
return { plugin: mod.applePlugin, seedFromConfig: mod.seedFromConfig };
|
|
750
1189
|
},
|
|
751
1190
|
defaultFallback(cfg) {
|
|
@@ -770,7 +1209,7 @@ var SERVICE_REGISTRY = {
|
|
|
770
1209
|
label: "Microsoft Entra ID OAuth 2.0 / OpenID Connect emulator",
|
|
771
1210
|
endpoints: "OAuth authorize, token exchange, userinfo, OIDC discovery, Graph /me, logout, token revocation",
|
|
772
1211
|
async load() {
|
|
773
|
-
const mod = await import("./dist-
|
|
1212
|
+
const mod = await import("./dist-IFULY5LE.js");
|
|
774
1213
|
return { plugin: mod.microsoftPlugin, seedFromConfig: mod.seedFromConfig };
|
|
775
1214
|
},
|
|
776
1215
|
defaultFallback(cfg) {
|
|
@@ -795,7 +1234,7 @@ var SERVICE_REGISTRY = {
|
|
|
795
1234
|
label: "Okta OAuth 2.0 / OpenID Connect + management API emulator",
|
|
796
1235
|
endpoints: "OIDC discovery, JWKS, OAuth authorize/token/userinfo/introspect/revoke/logout, users, groups, apps, authorization servers",
|
|
797
1236
|
async load() {
|
|
798
|
-
const mod = await import("./dist-
|
|
1237
|
+
const mod = await import("./dist-XWWZVLQQ.js");
|
|
799
1238
|
return { plugin: mod.oktaPlugin, seedFromConfig: mod.seedFromConfig };
|
|
800
1239
|
},
|
|
801
1240
|
defaultFallback(cfg) {
|
|
@@ -823,7 +1262,7 @@ var SERVICE_REGISTRY = {
|
|
|
823
1262
|
label: "AWS cloud service emulator",
|
|
824
1263
|
endpoints: "S3 (buckets, objects), SQS (queues, messages), IAM (users, roles, access keys), STS (assume role, caller identity)",
|
|
825
1264
|
async load() {
|
|
826
|
-
const mod = await import("./dist-
|
|
1265
|
+
const mod = await import("./dist-DSJSF3GY.js");
|
|
827
1266
|
return { plugin: mod.awsPlugin, seedFromConfig: mod.seedFromConfig };
|
|
828
1267
|
},
|
|
829
1268
|
defaultFallback() {
|
|
@@ -845,7 +1284,7 @@ var SERVICE_REGISTRY = {
|
|
|
845
1284
|
label: "Resend email API emulator",
|
|
846
1285
|
endpoints: "emails, domains, contacts, API keys, inbox UI",
|
|
847
1286
|
async load() {
|
|
848
|
-
const mod = await import("./dist-
|
|
1287
|
+
const mod = await import("./dist-R3TNKUIE.js");
|
|
849
1288
|
return { plugin: mod.resendPlugin, seedFromConfig: mod.seedFromConfig };
|
|
850
1289
|
},
|
|
851
1290
|
defaultFallback() {
|
|
@@ -862,7 +1301,7 @@ var SERVICE_REGISTRY = {
|
|
|
862
1301
|
label: "Stripe payments emulator",
|
|
863
1302
|
endpoints: "customers, payment methods, customer sessions, payment intents, charges, products, prices, checkout sessions, webhooks",
|
|
864
1303
|
async load() {
|
|
865
|
-
const mod = await import("./dist-
|
|
1304
|
+
const mod = await import("./dist-NJJLJT2N.js");
|
|
866
1305
|
return { plugin: mod.stripePlugin, seedFromConfig: mod.seedFromConfig };
|
|
867
1306
|
},
|
|
868
1307
|
defaultFallback() {
|
|
@@ -880,7 +1319,7 @@ var SERVICE_REGISTRY = {
|
|
|
880
1319
|
label: "MongoDB Atlas service emulator",
|
|
881
1320
|
endpoints: "Atlas Admin API v2 (projects, clusters, database users, databases, collections), Atlas Data API v1 (findOne, find, insertOne, insertMany, updateOne, updateMany, deleteOne, deleteMany, aggregate)",
|
|
882
1321
|
async load() {
|
|
883
|
-
const mod = await import("./dist-
|
|
1322
|
+
const mod = await import("./dist-2ZZGNPJI.js");
|
|
884
1323
|
return { plugin: mod.mongoatlasPlugin, seedFromConfig: mod.seedFromConfig };
|
|
885
1324
|
},
|
|
886
1325
|
defaultFallback() {
|
|
@@ -899,7 +1338,7 @@ var SERVICE_REGISTRY = {
|
|
|
899
1338
|
label: "Clerk authentication and user management emulator",
|
|
900
1339
|
endpoints: "OIDC discovery, JWKS, OAuth authorize/token/userinfo, users, email addresses, organizations, memberships, invitations, sessions",
|
|
901
1340
|
async load() {
|
|
902
|
-
const mod = await import("./dist-
|
|
1341
|
+
const mod = await import("./dist-IRUBHCZU.js");
|
|
903
1342
|
return { plugin: mod.clerkPlugin, seedFromConfig: mod.seedFromConfig };
|
|
904
1343
|
},
|
|
905
1344
|
defaultFallback(cfg) {
|
|
@@ -949,7 +1388,6 @@ var DEFAULT_TOKENS = {
|
|
|
949
1388
|
};
|
|
950
1389
|
|
|
951
1390
|
// src/commands/start.ts
|
|
952
|
-
import { serve } from "@hono/node-server";
|
|
953
1391
|
import { readFileSync as readFileSync2, existsSync } from "fs";
|
|
954
1392
|
import { resolve } from "path";
|
|
955
1393
|
import { parse as parseYaml } from "yaml";
|
|
@@ -1053,7 +1491,7 @@ function resolveBaseUrl(opts) {
|
|
|
1053
1491
|
}
|
|
1054
1492
|
|
|
1055
1493
|
// src/commands/start.ts
|
|
1056
|
-
var pkg = { version: "0.
|
|
1494
|
+
var pkg = { version: "0.6.0" };
|
|
1057
1495
|
function loadSeedConfig(seedPath) {
|
|
1058
1496
|
if (seedPath) {
|
|
1059
1497
|
const fullPath = resolve(seedPath);
|
|
@@ -1214,7 +1652,7 @@ function printBanner(services, tokens, configSource) {
|
|
|
1214
1652
|
if (configSource) {
|
|
1215
1653
|
lines.push(` ${pc.dim("Config:")} ${configSource}`);
|
|
1216
1654
|
} else {
|
|
1217
|
-
lines.push(` ${pc.dim("Config:")} defaults ${pc.dim("(run")} emulate init ${pc.dim("to customize)")}`);
|
|
1655
|
+
lines.push(` ${pc.dim("Config:")} defaults ${pc.dim("(run")} npx emulate init ${pc.dim("to customize)")}`);
|
|
1218
1656
|
}
|
|
1219
1657
|
lines.push("");
|
|
1220
1658
|
console.log(lines.join("\n"));
|
|
@@ -1249,7 +1687,7 @@ function initCommand(options) {
|
|
|
1249
1687
|
writeFileSync(fullPath, content, "utf-8");
|
|
1250
1688
|
console.log(`Created ${filename}`);
|
|
1251
1689
|
console.log(`
|
|
1252
|
-
Run 'emulate' to start the emulator.`);
|
|
1690
|
+
Run 'npx emulate' to start the emulator.`);
|
|
1253
1691
|
}
|
|
1254
1692
|
|
|
1255
1693
|
// src/commands/list.ts
|
|
@@ -1263,7 +1701,7 @@ function listCommand() {
|
|
|
1263
1701
|
}
|
|
1264
1702
|
|
|
1265
1703
|
// src/index.ts
|
|
1266
|
-
var pkg2 = { version: "0.
|
|
1704
|
+
var pkg2 = { version: "0.6.0" };
|
|
1267
1705
|
var defaultPort = process.env.EMULATE_PORT ?? process.env.PORT ?? "4000";
|
|
1268
1706
|
var program = new Command();
|
|
1269
1707
|
program.name("emulate").description("Local drop-in replacement services for CI and no-network sandboxes").version(pkg2.version);
|