@atlasauth/emulator 0.0.0-stage → 0.2.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/CHANGELOG.md ADDED
@@ -0,0 +1,15 @@
1
+ # @atlasauth/emulator changelog
2
+
3
+ ## Unreleased
4
+
5
+ ## 0.2.0 — 2026-11-11
6
+
7
+ ### Added
8
+
9
+ - `startProxy({ basePath })`: mount the Frontend API under a path (such as `/atlas`) on the same origin as your app.
10
+
11
+ ## 0.1.0 — 2026-10-26
12
+
13
+ ### Added
14
+
15
+ - First release. A local, in-memory Atlas for development: FAPI, a minimal BAPI, OIDC discovery, a mail/SMS catcher and a one-origin dev proxy.
package/Dockerfile ADDED
@@ -0,0 +1,9 @@
1
+ # docker build -t atlas-emulator -f packages/emulator/Dockerfile packages/emulator
2
+ # (after `pnpm --filter @atlasauth/emulator build`). Mount a seed file and pass --seed.
3
+ FROM node:22-alpine
4
+ WORKDIR /app
5
+ COPY dist ./dist
6
+ COPY package.json ./
7
+ RUN npm install --omit=dev --ignore-scripts
8
+ EXPOSE 4400
9
+ ENTRYPOINT ["node", "dist/bin.js", "--host", "0.0.0.0"]
package/README.md CHANGED
@@ -1,3 +1,19 @@
1
- # Temporary Holding Version
1
+ # @atlasauth/emulator
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ A local, in-memory Atlas for development and CI. No account, no network.
4
+
5
+ ```sh
6
+ npx @atlasauth/emulator --port 4400 --seed seed.json # or: atlas dev
7
+ ```
8
+
9
+ - **FAPI + minimal BAPI** (users, orgs, sessions, sign-in/up) backed by [`@atlasauth/msw`](../msw) state; point `NEXT_PUBLIC_ATLAS_FAPI_URL` / your SDK base URL at the printed origin.
10
+ - **Deterministic codes**: every email/SMS code is `424242` (`seed.instance.testOtp` overrides).
11
+ - **Mail and SMS catcher**: `/__emulator/mail` (UI) and `/__emulator/mail.json`.
12
+ - **OIDC discovery** at `/.well-known/openid-configuration`, JWKS at `/.well-known/jwks.json`.
13
+ - **One origin**: `--app http://localhost:3000` forwards everything the emulator does not own to your app. `atlas dev proxy --app <url> --api <fapi url>` does the same against a real instance.
14
+ - `POST /__emulator/reset` clears state.
15
+ - Docker: see `Dockerfile`.
16
+
17
+ `seed.json` is `{ "users": [{ "email": "ada@example.com", "password": "pw" }], "organizations": [] }`.
18
+
19
+ Limits: the emulator does not sign real tokens, run social/SAML flows or proxy WebSocket upgrades.
package/dist/bin.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/bin.js ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const node_fs_1 = require("node:fs");
5
+ const node_util_1 = require("node:util");
6
+ const server_1 = require("./server");
7
+ const { values } = (0, node_util_1.parseArgs)({ options: { port: { type: 'string' }, host: { type: 'string' }, seed: { type: 'string' }, app: { type: 'string' } } });
8
+ async function main() {
9
+ const emulator = await (0, server_1.startEmulator)({
10
+ port: values.port ? Number(values.port) : 4400,
11
+ host: values.host,
12
+ app: values.app,
13
+ seed: values.seed ? JSON.parse((0, node_fs_1.readFileSync)(values.seed, 'utf8')) : undefined,
14
+ });
15
+ console.log(`Atlas emulator on ${emulator.url} (mail catcher: ${emulator.url}/__emulator/mail)`);
16
+ process.once('SIGINT', () => void emulator.close().then(() => process.exit(0)));
17
+ process.once('SIGTERM', () => void emulator.close().then(() => process.exit(0)));
18
+ }
19
+ void main();
20
+ //# sourceMappingURL=bin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";;;AACA,qCAAuC;AACvC,yCAAsC;AACtC,qCAAyC;AAEzC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,qBAAS,EAAC,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;AACrJ,KAAK,UAAU,IAAI;IACjB,MAAM,QAAQ,GAAG,MAAM,IAAA,sBAAa,EAAC;QACnC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI;QAC9C,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAA,sBAAY,EAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS;KAC9E,CAAC,CAAC;IACH,OAAO,CAAC,GAAG,CAAC,qBAAqB,QAAQ,CAAC,GAAG,oBAAoB,QAAQ,CAAC,GAAG,mBAAmB,CAAC,CAAC;IAClG,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAChF,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACnF,CAAC;AAED,KAAK,IAAI,EAAE,CAAC"}
@@ -0,0 +1 @@
1
+ export { startEmulator, startProxy, type CaughtMessage, type Emulator, type EmulatorOptions, type ProxyOptions } from './server';
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.startProxy = exports.startEmulator = void 0;
4
+ var server_1 = require("./server");
5
+ Object.defineProperty(exports, "startEmulator", { enumerable: true, get: function () { return server_1.startEmulator; } });
6
+ Object.defineProperty(exports, "startProxy", { enumerable: true, get: function () { return server_1.startProxy; } });
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,mCAAiI;AAAxH,uGAAA,aAAa,OAAA;AAAE,oGAAA,UAAU,OAAA"}
@@ -0,0 +1,38 @@
1
+ import { type AtlasMock, type AtlasMockSeed } from '@atlasauth/msw';
2
+ export interface CaughtMessage {
3
+ id: number;
4
+ at: string;
5
+ channel: 'email' | 'sms';
6
+ to: string;
7
+ strategy: string;
8
+ code: string;
9
+ }
10
+ export interface EmulatorOptions {
11
+ port?: number;
12
+ host?: string;
13
+ seed?: AtlasMockSeed;
14
+ /** Proxy every path the emulator does not own to this app URL (one origin). */
15
+ app?: string;
16
+ }
17
+ export interface Emulator {
18
+ url: string;
19
+ mock: AtlasMock;
20
+ mail: CaughtMessage[];
21
+ close(): Promise<void>;
22
+ }
23
+ export declare function startEmulator(options?: EmulatorOptions): Promise<Emulator>;
24
+ export interface ProxyOptions {
25
+ port?: number;
26
+ host?: string;
27
+ /** Your app (e.g. http://localhost:3000). */
28
+ app: string;
29
+ /** The Atlas Frontend API to forward `/v1/*` and `/.well-known/*` to. */
30
+ api: string;
31
+ /** A path mount (e.g. `/atlas`): everything under it goes to the API with the prefix removed, the rest to the app. */
32
+ basePath?: string;
33
+ }
34
+ /** `atlas dev proxy`: one origin for the app and FAPI, so session cookies are first-party. */
35
+ export declare function startProxy(options: ProxyOptions): Promise<{
36
+ url: string;
37
+ close(): Promise<void>;
38
+ }>;
package/dist/server.js ADDED
@@ -0,0 +1,148 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.startEmulator = startEmulator;
4
+ exports.startProxy = startProxy;
5
+ /**
6
+ * The emulator: `@atlasauth/msw`'s in-memory FAPI/BAPI behind a real HTTP
7
+ * listener, plus OIDC discovery, a mail/SMS catcher and an optional one-origin
8
+ * proxy to your app (`app`), so cookies and CORS behave like production.
9
+ */
10
+ const node_http_1 = require("node:http");
11
+ const msw_1 = require("msw");
12
+ const msw_2 = require("@atlasauth/msw");
13
+ const HOP = new Set(['connection', 'keep-alive', 'transfer-encoding', 'upgrade', 'host', 'content-length']);
14
+ const esc = (s) => s.replace(/[&<>"]/g, (c) => `&#${c.charCodeAt(0)};`);
15
+ async function toRequest(req, origin) {
16
+ const chunks = [];
17
+ for await (const c of req)
18
+ chunks.push(c);
19
+ const body = chunks.length ? Buffer.concat(chunks) : undefined;
20
+ const headers = new Headers();
21
+ for (const [k, v] of Object.entries(req.headers))
22
+ if (v !== undefined)
23
+ headers.set(k, Array.isArray(v) ? v.join(', ') : v);
24
+ const method = req.method ?? 'GET';
25
+ return new Request(new URL(req.url ?? '/', origin), { method, headers, body: method === 'GET' || method === 'HEAD' ? undefined : body });
26
+ }
27
+ async function send(res, r) {
28
+ const headers = {};
29
+ r.headers.forEach((v, k) => {
30
+ if (!HOP.has(k) && k !== 'set-cookie')
31
+ headers[k] = v;
32
+ });
33
+ const cookies = r.headers.getSetCookie();
34
+ if (cookies.length)
35
+ headers['set-cookie'] = cookies;
36
+ res.writeHead(r.status, headers);
37
+ res.end(Buffer.from(await r.arrayBuffer()));
38
+ }
39
+ /** shortcut: no WebSocket upgrade proxying (framework HMR sockets), add when a dev server needs it. */
40
+ async function proxy(app, request) {
41
+ const url = new URL(request.url);
42
+ const target = new URL(url.pathname + url.search, app);
43
+ const headers = new Headers(request.headers);
44
+ headers.set('x-forwarded-host', url.host);
45
+ headers.delete('host');
46
+ try {
47
+ return await fetch(target, { method: request.method, headers, body: request.body, redirect: 'manual', duplex: 'half' });
48
+ }
49
+ catch (err) {
50
+ return new Response(`Atlas emulator could not reach ${app}: ${err.message}`, { status: 502 });
51
+ }
52
+ }
53
+ async function startEmulator(options = {}) {
54
+ const host = options.host ?? '127.0.0.1';
55
+ const mail = [];
56
+ const seen = new Set();
57
+ let origin = '';
58
+ // eslint-disable-next-line prefer-const -- assigned once below, but `harvest` closes over it before that point
59
+ let mock;
60
+ let handlers = [];
61
+ // The handlers mount on absolute URLs, so they are built once the port is known.
62
+ const harvest = () => {
63
+ for (const a of mock.attempts) {
64
+ if (!a.pendingCode || !a.identifier)
65
+ continue;
66
+ const key = `${a.id}:${a.strategy}:${a.pendingCode}`;
67
+ if (seen.has(key))
68
+ continue;
69
+ seen.add(key);
70
+ const sms = a.strategy === 'phone_code';
71
+ mail.push({ id: mail.length + 1, at: new Date().toISOString(), channel: sms ? 'sms' : 'email', to: a.identifier, strategy: a.strategy ?? 'verification', code: a.pendingCode });
72
+ }
73
+ };
74
+ const own = async (request) => {
75
+ const { pathname } = new URL(request.url);
76
+ if (pathname === '/.well-known/openid-configuration') {
77
+ return Response.json({
78
+ issuer: origin,
79
+ jwks_uri: `${origin}/.well-known/jwks.json`,
80
+ authorization_endpoint: `${origin}/oauth2/authorize`,
81
+ token_endpoint: `${origin}/oauth2/token`,
82
+ userinfo_endpoint: `${origin}/oauth2/userinfo`,
83
+ response_types_supported: ['code'],
84
+ subject_types_supported: ['public'],
85
+ id_token_signing_alg_values_supported: ['RS256'],
86
+ });
87
+ }
88
+ if (pathname === '/__emulator/mail.json')
89
+ return Response.json({ data: mail });
90
+ if (pathname === '/__emulator/mail') {
91
+ const rows = [...mail].reverse().map((m) => `<tr><td>${esc(m.at)}</td><td>${m.channel}</td><td>${esc(m.to)}</td><td>${esc(m.strategy)}</td><td><code>${esc(m.code)}</code></td></tr>`).join('');
92
+ return new Response(`<!doctype html><meta charset="utf-8"><title>Atlas emulator mail</title><h1>Caught messages</h1><table border="1" cellpadding="6"><tr><th>time</th><th>channel</th><th>to</th><th>strategy</th><th>code</th></tr>${rows || '<tr><td colspan="5">Nothing yet.</td></tr>'}</table>`, { headers: { 'content-type': 'text/html; charset=utf-8' } });
93
+ }
94
+ if (pathname === '/__emulator/reset' && request.method === 'POST') {
95
+ mock.reset();
96
+ mail.length = 0;
97
+ seen.clear();
98
+ return Response.json({ ok: true });
99
+ }
100
+ const res = await (0, msw_1.getResponse)(handlers, request);
101
+ if (res)
102
+ harvest();
103
+ return res ?? null;
104
+ };
105
+ const server = (0, node_http_1.createServer)((req, res) => {
106
+ void (async () => {
107
+ const request = await toRequest(req, origin);
108
+ const r = (await own(request)) ?? (options.app ? await proxy(options.app, request) : Response.json({ error: { code: 'NOT_FOUND', message: 'Not served by the emulator.' } }, { status: 404 }));
109
+ await send(res, r);
110
+ })().catch((err) => {
111
+ res.writeHead(500, { 'content-type': 'application/json' });
112
+ res.end(JSON.stringify({ error: { code: 'EMULATOR_ERROR', message: String(err.message) } }));
113
+ });
114
+ });
115
+ await new Promise((ok) => server.listen(options.port ?? 0, host, ok));
116
+ const addr = server.address();
117
+ const port = typeof addr === 'object' && addr ? addr.port : (options.port ?? 0);
118
+ origin = `http://${host === '0.0.0.0' ? 'localhost' : host}:${port}`;
119
+ const seed = options.seed ?? {};
120
+ mock = (0, msw_2.createAtlasMock)({ ...seed, instance: { ...seed.instance, fapiBaseUrl: origin, bapiBaseUrl: origin } });
121
+ handlers = (0, msw_2.atlasHandlers)(mock);
122
+ return { url: origin, mock, mail, close: () => new Promise((ok) => (server.closeAllConnections(), server.close(() => ok()))) };
123
+ }
124
+ /** `atlas dev proxy`: one origin for the app and FAPI, so session cookies are first-party. */
125
+ async function startProxy(options) {
126
+ const host = options.host ?? '127.0.0.1';
127
+ const server = (0, node_http_1.createServer)((req, res) => {
128
+ void (async () => {
129
+ const request = await toRequest(req, `http://${host}`);
130
+ const p = new URL(request.url).pathname;
131
+ const base = options.basePath?.replace(/\/+$/, '');
132
+ if (base && (p === base || p.startsWith(`${base}/`))) {
133
+ const u = new URL(request.url);
134
+ u.pathname = p.slice(base.length) || '/';
135
+ return void (await send(res, await proxy(options.api, new Request(u, request))));
136
+ }
137
+ const toApi = !base && (p.startsWith('/v1/') || p.startsWith('/.well-known/') || p.startsWith('/oauth2/'));
138
+ await send(res, await proxy(toApi ? options.api : options.app, request));
139
+ })().catch(() => {
140
+ res.writeHead(502);
141
+ res.end('proxy error');
142
+ });
143
+ });
144
+ await new Promise((ok) => server.listen(options.port ?? 0, host, ok));
145
+ const addr = server.address();
146
+ return { url: `http://${host}:${typeof addr === 'object' && addr ? addr.port : 0}`, close: () => new Promise((ok) => (server.closeAllConnections(), server.close(() => ok()))) };
147
+ }
148
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,41 @@
1
1
  {
2
2
  "name": "@atlasauth/emulator",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.2.0",
4
+ "description": "A local, in-memory Atlas for development: FAPI, a minimal BAPI, OIDC discovery, a mail/SMS catcher and a one-origin dev proxy.",
5
+ "bin": {
6
+ "atlas-emulator": "dist/bin.js"
7
+ },
8
+ "main": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "./package.json": "./package.json"
16
+ },
17
+ "dependencies": {
18
+ "msw": "^2.4.9",
19
+ "@atlasauth/msw": "0.3.0"
20
+ },
21
+ "devDependencies": {
22
+ "@types/node": "^22.9.0",
23
+ "typescript": "^5.6.3",
24
+ "vitest": "^2.1.4"
25
+ },
26
+ "publishConfig": {
27
+ "access": "public"
28
+ },
29
+ "files": [
30
+ "dist",
31
+ "!dist/*.tsbuildinfo",
32
+ "Dockerfile",
33
+ "README.md",
34
+ "CHANGELOG.md"
35
+ ],
36
+ "scripts": {
37
+ "build": "tsc -p tsconfig.build.json",
38
+ "typecheck": "tsgo -p tsconfig.json --noEmit --module preserve --moduleResolution bundler --incremental --tsBuildInfoFile node_modules/.cache/typecheck.tsbuildinfo",
39
+ "test": "vitest run"
40
+ }
6
41
  }