emuhealth 0.1.1 → 0.3.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 +12 -8
- package/dist/api.d.ts +4 -1
- package/dist/api.js +81 -21
- package/dist/api.js.map +1 -1
- package/dist/{chunk-GQ4IO5X5.js → chunk-VCQ3UPC5.js} +83 -30
- package/dist/chunk-VCQ3UPC5.js.map +1 -0
- package/dist/{dist-PLRHPEKZ.js → dist-22OZW7MU.js} +9 -7
- package/dist/dist-22OZW7MU.js.map +1 -0
- package/dist/{dist-EESUF62H.js → dist-575EVZLI.js} +9 -7
- package/dist/{dist-EESUF62H.js.map → dist-575EVZLI.js.map} +1 -1
- package/dist/{dist-M5AWLPBU.js → dist-ATXASBBA.js} +9 -7
- package/dist/dist-ATXASBBA.js.map +1 -0
- package/dist/{dist-EGN5EUC3.js → dist-B4K5JXTS.js} +9 -7
- package/dist/dist-B4K5JXTS.js.map +1 -0
- package/dist/{dist-A2VVAQ3G.js → dist-EUMN2OAH.js} +9 -7
- package/dist/dist-EUMN2OAH.js.map +1 -0
- package/dist/{dist-B5YXZCS3.js → dist-IMIDQ6CJ.js} +9 -7
- package/dist/dist-IMIDQ6CJ.js.map +1 -0
- package/dist/{dist-H6TJ2XTL.js → dist-KAYD3L2O.js} +9 -7
- package/dist/dist-KAYD3L2O.js.map +1 -0
- package/dist/{dist-FJPSLFJD.js → dist-KRJZAPPL.js} +9 -7
- package/dist/dist-KRJZAPPL.js.map +1 -0
- package/dist/{dist-SOYGDR4W.js → dist-L3SNHIRB.js} +9 -7
- package/dist/dist-L3SNHIRB.js.map +1 -0
- package/dist/{dist-7UXL7QGA.js → dist-M5TIXC2F.js} +9 -7
- package/dist/dist-M5TIXC2F.js.map +1 -0
- package/dist/dist-WLTGCLZF.js +1531 -0
- package/dist/dist-WLTGCLZF.js.map +1 -0
- package/dist/{dist-QJ24W3VN.js → dist-YK2XJNH7.js} +9 -7
- package/dist/dist-YK2XJNH7.js.map +1 -0
- package/dist/{dist-C6Y6IXLU.js → dist-YMRASK5I.js} +9 -7
- package/dist/dist-YMRASK5I.js.map +1 -0
- package/dist/{dist-J2Q7BESS.js → dist-ZGCIWJJM.js} +9 -7
- package/dist/dist-ZGCIWJJM.js.map +1 -0
- package/dist/index.js +24 -11
- package/dist/index.js.map +1 -1
- package/dist/project-worker.js +1 -1
- package/package.json +7 -6
- package/dist/chunk-GQ4IO5X5.js.map +0 -1
- package/dist/dist-7UXL7QGA.js.map +0 -1
- package/dist/dist-A2VVAQ3G.js.map +0 -1
- package/dist/dist-B5YXZCS3.js.map +0 -1
- package/dist/dist-C6Y6IXLU.js.map +0 -1
- package/dist/dist-EGN5EUC3.js.map +0 -1
- package/dist/dist-FJPSLFJD.js.map +0 -1
- package/dist/dist-H6TJ2XTL.js.map +0 -1
- package/dist/dist-J2Q7BESS.js.map +0 -1
- package/dist/dist-M5AWLPBU.js.map +0 -1
- package/dist/dist-PLRHPEKZ.js.map +0 -1
- package/dist/dist-QJ24W3VN.js.map +0 -1
- package/dist/dist-SOYGDR4W.js.map +0 -1
package/README.md
CHANGED
|
@@ -35,6 +35,10 @@ All services listen on IPv4 loopback (`127.0.0.1`) by default. No config file ne
|
|
|
35
35
|
- **Linear** on `http://localhost:4012`
|
|
36
36
|
- **Twilio** on `http://localhost:4013`
|
|
37
37
|
|
|
38
|
+
Health and life science services use a fixed range starting at `http://localhost:4100`. Each health service keeps its port no matter which other services run or how many upstream services exist.
|
|
39
|
+
|
|
40
|
+
- **FHIR R4** on `http://localhost:4100` (create, read, update, JSON Patch, delete, versioning, `_history`, search, batch and transaction Bundles, and a CapabilityStatement at `/metadata`; SMART on FHIR is on the roadmap)
|
|
41
|
+
|
|
38
42
|
Stripe webhooks configured with a secret include a `Stripe-Signature` header signed over the timestamp and raw request body.
|
|
39
43
|
|
|
40
44
|
Slack event callbacks use `X-Slack-Request-Timestamp` and `X-Slack-Signature` when `slack.signing_secret` is configured. The signature is an HMAC-SHA256 over `v0:<timestamp>:<raw-body>`; configure the receiver with the same secret and verify against the unparsed request body. Existing event subscriptions remain unsigned when the secret is absent or empty.
|
|
@@ -82,13 +86,13 @@ try {
|
|
|
82
86
|
}
|
|
83
87
|
```
|
|
84
88
|
|
|
85
|
-
Use `defineConfig({ services: { acme: { emulator: acme }, github: { emulator: 'github' } } })` in `emulate.config.ts
|
|
89
|
+
Use `defineConfig({ services: { acme: { emulator: acme }, github: { emulator: 'github' } } })` in `emuhealth.config.ts` (`emulate.config.ts` also works). YAML/JSON entries accept local module paths and installed packages. `--config` selects a config explicitly; legacy flat configs and `--seed` remain supported. Node loads local TypeScript with path aliases and source locations without additional runtime dependencies. Node 26 supports erasable TypeScript only; compile enums and parameter properties to JavaScript before loading them. Node 24 also supports native TypeScript transforms.
|
|
86
90
|
|
|
87
91
|
Custom state uses your own record shapes and IDs. Seeds replace the complete initial state. Reset restores the captured seed; successful watch reloads create a new baseline and reset the run. With config auto-discovery, watch mode also detects recognized config files created after startup. Instances are independent. Persistence is opt-in, with versioned snapshots and no cross-process locking. Use `port: 0` for HTTP tests, or `listen: false` to test without opening a port. Custom reset and close are awaitable. Framework adapters keep root-relative custom redirects under the service mount while preserving custom HTML bodies.
|
|
88
92
|
|
|
89
93
|
Streamed responses persist state changes when their bodies finish or are canceled. Reset and close cancel active streams before running cleanup. `c.header('Set-Cookie', value, { append: true })` retains cookies already set on the response. In a Next.js route, export `OPTIONS` from `createEmulateHandler` to forward preflight requests and custom OPTIONS handlers.
|
|
90
94
|
|
|
91
|
-
See the [custom emulator guide](https://
|
|
95
|
+
See the [custom emulator guide](https://www.emuhealth.dev/docs/custom-emulators) and [complete inventory example](examples/custom-api) for validation, middleware, persistence, adapters, package sharing, and troubleshooting.
|
|
92
96
|
|
|
93
97
|
## CLI
|
|
94
98
|
|
|
@@ -122,7 +126,7 @@ npx emuhealth list
|
|
|
122
126
|
|
|
123
127
|
| Flag | Default | Description |
|
|
124
128
|
|------|---------|-------------|
|
|
125
|
-
| `-p, --port` | `4000` | Base port (auto-increments per service) |
|
|
129
|
+
| `-p, --port` | `4000` | Base port (auto-increments per service; health services start at base + 100) |
|
|
126
130
|
| `--host` | `127.0.0.1` | Listening address; use `0.0.0.0` to allow network access |
|
|
127
131
|
| `-s, --service` | all | Comma-separated services to enable |
|
|
128
132
|
| `--seed` | auto-detect | Path to seed config (YAML or JSON) |
|
|
@@ -130,7 +134,7 @@ npx emuhealth list
|
|
|
130
134
|
| `--portless` | off | Serve over HTTPS via portless (auto-registers aliases) |
|
|
131
135
|
| `--generated-secrets-file` | none | Generate omitted service secrets and write them to a new owner-only JSON file |
|
|
132
136
|
|
|
133
|
-
The port can also be set via `
|
|
137
|
+
The port can also be set via the `EMUHEALTH_PORT` or `PORT` environment variables. The upstream name `EMULATE_PORT` still works when `EMUHEALTH_PORT` is not set.
|
|
134
138
|
|
|
135
139
|
For access from a container or another machine, use `npx emuhealth start --host 0.0.0.0`. Set `--base-url` to a URL reachable by those clients when using OAuth redirects or other advertised URLs.
|
|
136
140
|
|
|
@@ -158,13 +162,13 @@ If portless is not installed, emulate will prompt to install it (`npm i -g portl
|
|
|
158
162
|
|
|
159
163
|
The `--portless` flag overwrites any existing portless aliases matching `*.emulate`. Aliases are removed automatically when emulate shuts down.
|
|
160
164
|
|
|
161
|
-
For a custom base URL without portless (any reverse proxy), use `--base-url` or the `
|
|
165
|
+
For a custom base URL without portless (any reverse proxy), use `--base-url` or the `EMUHEALTH_BASE_URL` env var (`EMULATE_BASE_URL` also works):
|
|
162
166
|
|
|
163
167
|
```bash
|
|
164
168
|
npx emuhealth start --base-url "https://{service}.myproxy.test"
|
|
165
169
|
```
|
|
166
170
|
|
|
167
|
-
The `PORTLESS_URL` env var is automatically set by the `portless` CLI wrapper when running a command through it (e.g. `portless github.emulate emuhealth start`), typically to a value like `https://{service}.emulate.localhost`. It supports `{service}` interpolation, just like `--base-url` and `
|
|
171
|
+
The `PORTLESS_URL` env var is automatically set by the `portless` CLI wrapper when running a command through it (e.g. `portless github.emulate emuhealth start`), typically to a value like `https://{service}.emulate.localhost`. It supports `{service}` interpolation, just like `--base-url` and `EMUHEALTH_BASE_URL`. When no explicit `baseUrl` is provided, it is used as a fallback.
|
|
168
172
|
|
|
169
173
|
Per-service overrides are also supported in the seed config (these take highest priority over all other base URL sources):
|
|
170
174
|
|
|
@@ -258,7 +262,7 @@ afterAll(() => Promise.all([github.close(), vercel.close()]))
|
|
|
258
262
|
| `port` | `4000` | Port for the HTTP server |
|
|
259
263
|
| `hostname` | `127.0.0.1` | Listening address for built-in and custom emulators |
|
|
260
264
|
| `seed` | none | Inline seed data (same shape as YAML config) |
|
|
261
|
-
| `baseUrl` | none | Override advertised base URL. Per-service `baseUrl` in seed config takes highest priority, then this option, then `
|
|
265
|
+
| `baseUrl` | none | Override advertised base URL. Per-service `baseUrl` in seed config takes highest priority, then this option, then `EMUHEALTH_BASE_URL` env var (or `EMULATE_BASE_URL`, supports `{service}`), then `PORTLESS_URL` (supports `{service}`, automatically set by the `portless` CLI wrapper), then `http://localhost:<port>`. |
|
|
262
266
|
|
|
263
267
|
Use `hostname: '0.0.0.0'` to allow connections from containers or other machines, and `baseUrl` to advertise a URL reachable by those clients.
|
|
264
268
|
|
|
@@ -273,7 +277,7 @@ Use `hostname: '0.0.0.0'` to allow connections from containers or other machines
|
|
|
273
277
|
|
|
274
278
|
## Configuration
|
|
275
279
|
|
|
276
|
-
Configuration is optional. The CLI auto-detects config files in this order: `emulate.config.yaml` / `.yml`, `emulate.config.json`, `service-emulator.config.yaml` / `.yml`, `service-emulator.config.json`. Or pass `--seed <file>` explicitly. Run `npx emuhealth init` to generate a starter file.
|
|
280
|
+
Configuration is optional. The CLI auto-detects config files in this order: `emuhealth.config.yaml` / `.yml`, `emuhealth.config.json`, then the upstream names `emulate.config.yaml` / `.yml`, `emulate.config.json`, `service-emulator.config.yaml` / `.yml`, `service-emulator.config.json`. An `emuhealth.config.*` file always wins over the upstream names. Or pass `--seed <file>` explicitly. Run `npx emuhealth init` to generate a starter file.
|
|
277
281
|
|
|
278
282
|
```yaml
|
|
279
283
|
tokens:
|
package/dist/api.d.ts
CHANGED
|
@@ -249,8 +249,11 @@ declare function defineConfig<Definitions extends Record<string, EmulatorDefinit
|
|
|
249
249
|
tokens?: EmulateConfig["tokens"];
|
|
250
250
|
}): typeof config;
|
|
251
251
|
|
|
252
|
+
declare const HEALTH_SERVICE_NAME_LIST: readonly ["fhir"];
|
|
253
|
+
type HealthServiceName = (typeof HEALTH_SERVICE_NAME_LIST)[number];
|
|
254
|
+
|
|
252
255
|
declare const SERVICE_NAME_LIST: readonly ["vercel", "github", "google", "slack", "apple", "microsoft", "okta", "aws", "resend", "stripe", "mongoatlas", "clerk", "linear", "twilio"];
|
|
253
|
-
type ServiceName = (typeof SERVICE_NAME_LIST)[number];
|
|
256
|
+
type ServiceName = (typeof SERVICE_NAME_LIST)[number] | HealthServiceName;
|
|
254
257
|
|
|
255
258
|
interface SeedConfig {
|
|
256
259
|
tokens?: Record<string, {
|
package/dist/api.js
CHANGED
|
@@ -832,7 +832,7 @@ function createErrorHandler(documentationUrl) {
|
|
|
832
832
|
};
|
|
833
833
|
}
|
|
834
834
|
var errorHandler = createErrorHandler();
|
|
835
|
-
var isDebug = typeof process !== "undefined" && (process.env.DEBUG === "1" || process.env.DEBUG === "true" || process.env.EMULATE_DEBUG === "1");
|
|
835
|
+
var isDebug = typeof process !== "undefined" && (process.env.DEBUG === "1" || process.env.DEBUG === "true" || process.env.EMULATE_DEBUG === "1" || process.env.EMUHEALTH_DEBUG === "1");
|
|
836
836
|
function debug(label, ...args) {
|
|
837
837
|
if (isDebug) {
|
|
838
838
|
console.log(`[${label}]`, ...args);
|
|
@@ -1256,15 +1256,17 @@ body{
|
|
|
1256
1256
|
.checkout-form-side{padding:32px 20px;}
|
|
1257
1257
|
}
|
|
1258
1258
|
`;
|
|
1259
|
-
var
|
|
1259
|
+
var PROJECT_URL = "https://www.emuhealth.dev";
|
|
1260
|
+
var REPO_URL = "https://github.com/emuhealth/emuhealth";
|
|
1261
|
+
var POWERED_BY = `<div class="powered-by">Powered by <a href="${PROJECT_URL}" target="_blank" rel="noopener">emuhealth</a></div>`;
|
|
1260
1262
|
function emuBar(service) {
|
|
1261
1263
|
const title = service ? `${escapeHtml(service)} Emulator` : "Emulator";
|
|
1262
1264
|
return `<div class="emu-bar">
|
|
1263
1265
|
<span class="emu-bar-title">${title}</span>
|
|
1264
1266
|
<nav class="emu-bar-links">
|
|
1265
|
-
<a href="
|
|
1266
|
-
<a href="
|
|
1267
|
-
<a href="
|
|
1267
|
+
<a href="${REPO_URL}/issues" target="_blank" rel="noopener"><span class="full">Report Issue</span><span class="short">Report</span></a>
|
|
1268
|
+
<a href="${REPO_URL}" target="_blank" rel="noopener"><span class="full">Source Code</span><span class="short">Source</span></a>
|
|
1269
|
+
<a href="${PROJECT_URL}" target="_blank" rel="noopener"><span class="full">Learn More</span><span class="short">Learn</span></a>
|
|
1268
1270
|
</nav>
|
|
1269
1271
|
</div>`;
|
|
1270
1272
|
}
|
|
@@ -1275,7 +1277,7 @@ function head(title) {
|
|
|
1275
1277
|
<meta charset="utf-8"/>
|
|
1276
1278
|
<meta name="viewport" content="width=device-width,initial-scale=1"/>
|
|
1277
1279
|
<link rel="icon" href="/_emulate/favicon.ico"/>
|
|
1278
|
-
<title>${escapeHtml(title)} |
|
|
1280
|
+
<title>${escapeHtml(title)} | emuhealth</title>
|
|
1279
1281
|
<style>${CSS}</style>
|
|
1280
1282
|
</head>`;
|
|
1281
1283
|
}
|
|
@@ -1937,13 +1939,66 @@ function defineConfig(config) {
|
|
|
1937
1939
|
return config;
|
|
1938
1940
|
}
|
|
1939
1941
|
|
|
1942
|
+
// src/registry-health.ts
|
|
1943
|
+
var HEALTH_SERVICE_NAME_LIST = ["fhir"];
|
|
1944
|
+
var HEALTH_SERVICE_NAMES = HEALTH_SERVICE_NAME_LIST;
|
|
1945
|
+
var HEALTH_SERVICE_REGISTRY = {
|
|
1946
|
+
fhir: {
|
|
1947
|
+
label: "FHIR R4 server emulator",
|
|
1948
|
+
endpoints: "create, read, vread, update (including create on update), JSON Patch, logical delete, _history, search with includes and chaining, batch and transaction Bundles, CapabilityStatement at /metadata, ETag and If-Match",
|
|
1949
|
+
async load() {
|
|
1950
|
+
const mod = await import("./dist-WLTGCLZF.js");
|
|
1951
|
+
return { plugin: mod.fhirPlugin, seedFromConfig: mod.seedFromConfig };
|
|
1952
|
+
},
|
|
1953
|
+
defaultFallback() {
|
|
1954
|
+
return { login: "fhir-user", id: 1, scopes: [] };
|
|
1955
|
+
},
|
|
1956
|
+
initConfig: {
|
|
1957
|
+
fhir: {
|
|
1958
|
+
resources: [
|
|
1959
|
+
{
|
|
1960
|
+
resourceType: "Patient",
|
|
1961
|
+
id: "synthetic-patient-1",
|
|
1962
|
+
name: [{ family: "Example", given: ["Jamie"] }],
|
|
1963
|
+
gender: "female",
|
|
1964
|
+
birthDate: "1980-01-01"
|
|
1965
|
+
}
|
|
1966
|
+
]
|
|
1967
|
+
}
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1970
|
+
};
|
|
1971
|
+
var HEALTH_PORT_OFFSET = 100;
|
|
1972
|
+
function defaultServicePort(service, basePort, index, healthNames = HEALTH_SERVICE_NAMES) {
|
|
1973
|
+
const healthIndex = healthNames.indexOf(service);
|
|
1974
|
+
return healthIndex === -1 ? basePort + index : basePort + HEALTH_PORT_OFFSET + healthIndex;
|
|
1975
|
+
}
|
|
1976
|
+
|
|
1940
1977
|
// src/registry.ts
|
|
1978
|
+
var SERVICE_NAME_LIST = [
|
|
1979
|
+
"vercel",
|
|
1980
|
+
"github",
|
|
1981
|
+
"google",
|
|
1982
|
+
"slack",
|
|
1983
|
+
"apple",
|
|
1984
|
+
"microsoft",
|
|
1985
|
+
"okta",
|
|
1986
|
+
"aws",
|
|
1987
|
+
"resend",
|
|
1988
|
+
"stripe",
|
|
1989
|
+
"mongoatlas",
|
|
1990
|
+
"clerk",
|
|
1991
|
+
"linear",
|
|
1992
|
+
"twilio"
|
|
1993
|
+
];
|
|
1994
|
+
var SERVICE_NAMES = [...SERVICE_NAME_LIST, ...HEALTH_SERVICE_NAMES];
|
|
1941
1995
|
var SERVICE_REGISTRY = {
|
|
1996
|
+
...HEALTH_SERVICE_REGISTRY,
|
|
1942
1997
|
vercel: {
|
|
1943
1998
|
label: "Vercel REST API emulator",
|
|
1944
1999
|
endpoints: "projects, deployments, domains, env vars, users, teams, file uploads, protection bypass, blob storage",
|
|
1945
2000
|
async load() {
|
|
1946
|
-
const mod = await import("./dist-
|
|
2001
|
+
const mod = await import("./dist-YK2XJNH7.js");
|
|
1947
2002
|
return { plugin: mod.vercelPlugin, seedFromConfig: mod.seedFromConfig };
|
|
1948
2003
|
},
|
|
1949
2004
|
defaultFallback(cfg) {
|
|
@@ -1970,7 +2025,7 @@ var SERVICE_REGISTRY = {
|
|
|
1970
2025
|
label: "GitHub REST API emulator",
|
|
1971
2026
|
endpoints: "users, repos, issues, PRs, comments, reviews, labels, milestones, branches, git data, orgs, teams, releases, webhooks, search, actions, checks, rate limit",
|
|
1972
2027
|
async load() {
|
|
1973
|
-
const mod = await import("./dist-
|
|
2028
|
+
const mod = await import("./dist-M5TIXC2F.js");
|
|
1974
2029
|
return {
|
|
1975
2030
|
plugin: mod.githubPlugin,
|
|
1976
2031
|
seedFromConfig: mod.seedFromConfig,
|
|
@@ -2034,7 +2089,7 @@ var SERVICE_REGISTRY = {
|
|
|
2034
2089
|
label: "Google OAuth 2.0 / OpenID Connect + Gmail, Calendar, and Drive emulator",
|
|
2035
2090
|
endpoints: "OAuth authorize, token exchange, userinfo, RS256 OIDC discovery and JWKS, token revocation, Gmail messages/drafts/threads/labels/history/settings, Calendar discovery/lists/events/freebusy, Drive files/uploads",
|
|
2036
2091
|
async load() {
|
|
2037
|
-
const mod = await import("./dist-
|
|
2092
|
+
const mod = await import("./dist-575EVZLI.js");
|
|
2038
2093
|
return { plugin: mod.googlePlugin, seedFromConfig: mod.seedFromConfig };
|
|
2039
2094
|
},
|
|
2040
2095
|
defaultFallback(cfg) {
|
|
@@ -2116,7 +2171,7 @@ var SERVICE_REGISTRY = {
|
|
|
2116
2171
|
label: "Slack API emulator",
|
|
2117
2172
|
endpoints: "auth, chat, conversations, users, profiles, presence, files, pins, bookmarks, views, reactions, team, OAuth, incoming webhooks, inspector",
|
|
2118
2173
|
async load() {
|
|
2119
|
-
const mod = await import("./dist-
|
|
2174
|
+
const mod = await import("./dist-IMIDQ6CJ.js");
|
|
2120
2175
|
return { plugin: mod.slackPlugin, seedFromConfig: mod.seedFromConfig };
|
|
2121
2176
|
},
|
|
2122
2177
|
defaultFallback() {
|
|
@@ -2197,7 +2252,7 @@ var SERVICE_REGISTRY = {
|
|
|
2197
2252
|
label: "Apple Sign In / OAuth emulator",
|
|
2198
2253
|
endpoints: "OAuth authorize, token exchange, JWKS",
|
|
2199
2254
|
async load() {
|
|
2200
|
-
const mod = await import("./dist-
|
|
2255
|
+
const mod = await import("./dist-L3SNHIRB.js");
|
|
2201
2256
|
return { plugin: mod.applePlugin, seedFromConfig: mod.seedFromConfig };
|
|
2202
2257
|
},
|
|
2203
2258
|
defaultFallback(cfg) {
|
|
@@ -2222,7 +2277,7 @@ var SERVICE_REGISTRY = {
|
|
|
2222
2277
|
label: "Microsoft Entra ID OAuth 2.0 / OpenID Connect emulator",
|
|
2223
2278
|
endpoints: "OAuth authorize, token exchange, userinfo, OIDC discovery, Graph /me, logout, token revocation",
|
|
2224
2279
|
async load() {
|
|
2225
|
-
const mod = await import("./dist-
|
|
2280
|
+
const mod = await import("./dist-ZGCIWJJM.js");
|
|
2226
2281
|
return { plugin: mod.microsoftPlugin, seedFromConfig: mod.seedFromConfig };
|
|
2227
2282
|
},
|
|
2228
2283
|
defaultFallback(cfg) {
|
|
@@ -2247,7 +2302,7 @@ var SERVICE_REGISTRY = {
|
|
|
2247
2302
|
label: "Okta OAuth 2.0 / OpenID Connect + management API emulator",
|
|
2248
2303
|
endpoints: "OIDC discovery, JWKS, OAuth authorize/token/userinfo/introspect/revoke/logout, users, groups, apps, authorization servers",
|
|
2249
2304
|
async load() {
|
|
2250
|
-
const mod = await import("./dist-
|
|
2305
|
+
const mod = await import("./dist-EUMN2OAH.js");
|
|
2251
2306
|
return { plugin: mod.oktaPlugin, seedFromConfig: mod.seedFromConfig };
|
|
2252
2307
|
},
|
|
2253
2308
|
defaultFallback(cfg) {
|
|
@@ -2275,7 +2330,7 @@ var SERVICE_REGISTRY = {
|
|
|
2275
2330
|
label: "AWS cloud service emulator",
|
|
2276
2331
|
endpoints: "S3 (buckets, objects), SQS (queues, messages), Cognito (User Pools, OAuth, JWTs, Identity Pools), IAM (users, roles, access keys), STS (assume role, caller identity)",
|
|
2277
2332
|
async load() {
|
|
2278
|
-
const mod = await import("./dist-
|
|
2333
|
+
const mod = await import("./dist-22OZW7MU.js");
|
|
2279
2334
|
return { plugin: mod.awsPlugin, seedFromConfig: mod.seedFromConfig };
|
|
2280
2335
|
},
|
|
2281
2336
|
defaultFallback() {
|
|
@@ -2297,7 +2352,7 @@ var SERVICE_REGISTRY = {
|
|
|
2297
2352
|
label: "Resend email API emulator",
|
|
2298
2353
|
endpoints: "emails with idempotency, recipient restrictions, send attempts, domains, contacts, API keys, inbox UI",
|
|
2299
2354
|
async load() {
|
|
2300
|
-
const mod = await import("./dist-
|
|
2355
|
+
const mod = await import("./dist-B4K5JXTS.js");
|
|
2301
2356
|
return { plugin: mod.resendPlugin, seedFromConfig: mod.seedFromConfig };
|
|
2302
2357
|
},
|
|
2303
2358
|
defaultFallback() {
|
|
@@ -2314,7 +2369,7 @@ var SERVICE_REGISTRY = {
|
|
|
2314
2369
|
label: "Stripe payments emulator",
|
|
2315
2370
|
endpoints: "customers, payment methods, customer sessions, payment intents, charges, products, prices, checkout sessions, webhooks",
|
|
2316
2371
|
async load() {
|
|
2317
|
-
const mod = await import("./dist-
|
|
2372
|
+
const mod = await import("./dist-KRJZAPPL.js");
|
|
2318
2373
|
return { plugin: mod.stripePlugin, seedFromConfig: mod.seedFromConfig };
|
|
2319
2374
|
},
|
|
2320
2375
|
defaultFallback() {
|
|
@@ -2351,7 +2406,7 @@ var SERVICE_REGISTRY = {
|
|
|
2351
2406
|
label: "Clerk authentication and user management emulator",
|
|
2352
2407
|
endpoints: "OIDC discovery, JWKS, OAuth authorize/token/userinfo, users, email addresses, organizations, memberships, invitations, sessions",
|
|
2353
2408
|
async load() {
|
|
2354
|
-
const mod = await import("./dist-
|
|
2409
|
+
const mod = await import("./dist-YMRASK5I.js");
|
|
2355
2410
|
return { plugin: mod.clerkPlugin, seedFromConfig: mod.seedFromConfig };
|
|
2356
2411
|
},
|
|
2357
2412
|
defaultFallback(cfg) {
|
|
@@ -2390,7 +2445,7 @@ var SERVICE_REGISTRY = {
|
|
|
2390
2445
|
label: "Linear GraphQL API emulator",
|
|
2391
2446
|
endpoints: "GraphQL, OAuth, issues, teams, users, workflow states, comments, labels, projects, cycles, webhooks, agents, inspector",
|
|
2392
2447
|
async load() {
|
|
2393
|
-
const mod = await import("./dist-
|
|
2448
|
+
const mod = await import("./dist-ATXASBBA.js");
|
|
2394
2449
|
return { plugin: mod.linearPlugin, seedFromConfig: mod.seedFromConfig };
|
|
2395
2450
|
},
|
|
2396
2451
|
defaultFallback(cfg) {
|
|
@@ -2455,7 +2510,7 @@ var SERVICE_REGISTRY = {
|
|
|
2455
2510
|
label: "Twilio API emulator",
|
|
2456
2511
|
endpoints: "accounts, API keys, phone numbers, Programmable Messaging, Messaging Services, Verify, Voice, webhooks, simulator, inspector",
|
|
2457
2512
|
async load() {
|
|
2458
|
-
const mod = await import("./dist-
|
|
2513
|
+
const mod = await import("./dist-KAYD3L2O.js");
|
|
2459
2514
|
return { plugin: mod.twilioPlugin, seedFromConfig: mod.seedFromConfig };
|
|
2460
2515
|
},
|
|
2461
2516
|
defaultFallback(cfg) {
|
|
@@ -2509,6 +2564,11 @@ var SERVICE_REGISTRY = {
|
|
|
2509
2564
|
}
|
|
2510
2565
|
};
|
|
2511
2566
|
|
|
2567
|
+
// src/env.ts
|
|
2568
|
+
function brandedEnv(name) {
|
|
2569
|
+
return process.env[`EMUHEALTH_${name}`] || process.env[`EMULATE_${name}`] || void 0;
|
|
2570
|
+
}
|
|
2571
|
+
|
|
2512
2572
|
// src/base-url.ts
|
|
2513
2573
|
function resolveBaseUrl(opts) {
|
|
2514
2574
|
if (opts.seedBaseUrl) {
|
|
@@ -2517,7 +2577,7 @@ function resolveBaseUrl(opts) {
|
|
|
2517
2577
|
if (opts.baseUrl) {
|
|
2518
2578
|
return opts.baseUrl.replace(/\{service\}/g, opts.service);
|
|
2519
2579
|
}
|
|
2520
|
-
const envBaseUrl =
|
|
2580
|
+
const envBaseUrl = brandedEnv("BASE_URL");
|
|
2521
2581
|
if (envBaseUrl) {
|
|
2522
2582
|
return envBaseUrl.replace(/\{service\}/g, opts.service);
|
|
2523
2583
|
}
|
|
@@ -2594,7 +2654,7 @@ function closeHttpServer(server) {
|
|
|
2594
2654
|
});
|
|
2595
2655
|
}
|
|
2596
2656
|
async function createBuiltinEmulator(options) {
|
|
2597
|
-
const { service, port = 4e3, seed: seedConfig } = options;
|
|
2657
|
+
const { service, port = defaultServicePort(service, 4e3, 0), seed: seedConfig } = options;
|
|
2598
2658
|
const entry = SERVICE_REGISTRY[service];
|
|
2599
2659
|
if (!entry) {
|
|
2600
2660
|
throw new Error(`Unknown service: ${service}`);
|