@api-emulator/adapter-next 0.5.2 → 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 CHANGED
@@ -1,8 +1,8 @@
1
1
  # @api-emulator/adapter-next
2
2
 
3
- Next.js App Router integration for emulate. Embed emulators directly in your Next.js app so they run on the same origin, solving the Vercel preview deployment problem where OAuth callback URLs change with every deployment.
3
+ Next.js App Router integration for api-emulator. Embed emulators directly in your Next.js app so they run on the same origin, solving the Vercel preview deployment problem where OAuth callback URLs change with every deployment.
4
4
 
5
- Part of [emulate](https://github.com/jsj/api-emulator) — local drop-in replacement services for CI and no-network sandboxes.
5
+ Part of [api-emulator](https://github.com/jsj/api-emulator) — local drop-in replacement services for CI and no-network sandboxes.
6
6
 
7
7
  ## Install
8
8
 
@@ -15,8 +15,8 @@ npm install @api-emulator/adapter-next
15
15
  Create a catch-all route that serves emulator traffic:
16
16
 
17
17
  ```typescript
18
- // app/emulate/[...path]/route.ts
19
- import { createEmulateHandler } from '@api-emulator/adapter-next'
18
+ // app/api-emulator/[...path]/route.ts
19
+ import { createApiEmulatorHandler } from '@api-emulator/adapter-next'
20
20
  import type { ServicePlugin } from '@api-emulator/core'
21
21
 
22
22
  const localPlugin: ServicePlugin = {
@@ -26,7 +26,7 @@ const localPlugin: ServicePlugin = {
26
26
  },
27
27
  }
28
28
 
29
- export const { GET, POST, PUT, PATCH, DELETE } = createEmulateHandler({
29
+ export const { GET, POST, PUT, PATCH, DELETE } = createApiEmulatorHandler({
30
30
  services: {
31
31
  local: { emulator: { plugin: localPlugin } },
32
32
  },
@@ -47,9 +47,9 @@ const baseUrl = process.env.VERCEL_URL
47
47
  GitHub({
48
48
  clientId: 'any-value',
49
49
  clientSecret: 'any-value',
50
- authorization: { url: `${baseUrl}/emulate/github/login/oauth/authorize` },
51
- token: { url: `${baseUrl}/emulate/github/login/oauth/access_token` },
52
- userinfo: { url: `${baseUrl}/emulate/github/user` },
50
+ authorization: { url: `${baseUrl}/api-emulator/github/login/oauth/authorize` },
51
+ token: { url: `${baseUrl}/api-emulator/github/login/oauth/access_token` },
52
+ userinfo: { url: `${baseUrl}/api-emulator/github/user` },
53
53
  })
54
54
  ```
55
55
 
@@ -61,9 +61,9 @@ Emulator UI pages use bundled fonts. Wrap your Next.js config to include them in
61
61
 
62
62
  ```typescript
63
63
  // next.config.mjs
64
- import { withEmulate } from '@api-emulator/adapter-next'
64
+ import { withApiEmulator } from '@api-emulator/adapter-next'
65
65
 
66
- export default withEmulate({
66
+ export default withApiEmulator({
67
67
  // your normal Next.js config
68
68
  })
69
69
  ```
@@ -71,7 +71,7 @@ export default withEmulate({
71
71
  If you mount the catch-all at a custom path, pass the matching prefix:
72
72
 
73
73
  ```typescript
74
- export default withEmulate(nextConfig, { routePrefix: '/api/emulate' })
74
+ export default withApiEmulator(nextConfig, { routePrefix: '/api/api-emulator' })
75
75
  ```
76
76
 
77
77
  ## Persistence
@@ -79,7 +79,7 @@ export default withEmulate(nextConfig, { routePrefix: '/api/emulate' })
79
79
  By default, emulator state is in-memory and resets on every cold start. To persist state across restarts, pass a `persistence` adapter:
80
80
 
81
81
  ```typescript
82
- import { createEmulateHandler } from '@api-emulator/adapter-next'
82
+ import { createApiEmulatorHandler } from '@api-emulator/adapter-next'
83
83
  import type { ServicePlugin } from '@api-emulator/core'
84
84
 
85
85
  const localPlugin: ServicePlugin = {
@@ -92,7 +92,7 @@ const kvAdapter = {
92
92
  async save(data: string) { await kv.set('api-emulator-state', data) },
93
93
  }
94
94
 
95
- export const { GET, POST, PUT, PATCH, DELETE } = createEmulateHandler({
95
+ export const { GET, POST, PUT, PATCH, DELETE } = createApiEmulatorHandler({
96
96
  services: { local: { emulator: { plugin: localPlugin } } },
97
97
  persistence: kvAdapter,
98
98
  })
package/dist/index.d.ts CHANGED
@@ -11,7 +11,7 @@ interface EmulatorEntry {
11
11
  emulator: EmulatorModule;
12
12
  seed?: Record<string, unknown>;
13
13
  }
14
- interface EmulateHandlerConfig {
14
+ interface ApiEmulatorHandlerConfig {
15
15
  services: Record<string, EmulatorEntry>;
16
16
  persistence?: PersistenceAdapter;
17
17
  }
@@ -22,15 +22,15 @@ type RouteHandler = (req: NextRequest, ctx: {
22
22
  path: string[];
23
23
  }>;
24
24
  }) => Promise<NextResponse>;
25
- declare function createEmulateHandler(config: EmulateHandlerConfig): {
25
+ declare function createApiEmulatorHandler(config: ApiEmulatorHandlerConfig): {
26
26
  GET: RouteHandler;
27
27
  POST: RouteHandler;
28
28
  PUT: RouteHandler;
29
29
  PATCH: RouteHandler;
30
30
  DELETE: RouteHandler;
31
31
  };
32
- declare function withEmulate<T>(nextConfig: T, options?: {
32
+ declare function withApiEmulator<T>(nextConfig: T, options?: {
33
33
  routePrefix?: string;
34
34
  }): T;
35
35
 
36
- export { type EmulateHandlerConfig, type EmulatorModule, createEmulateHandler, withEmulate };
36
+ export { type ApiEmulatorHandlerConfig, type EmulatorModule, createApiEmulatorHandler, withApiEmulator };
package/dist/index.js CHANGED
@@ -101,7 +101,7 @@ async function rewriteResponse(response, servicePrefix) {
101
101
  headers
102
102
  });
103
103
  }
104
- function createEmulateHandler(config) {
104
+ function createApiEmulatorHandler(config) {
105
105
  const { services: serviceEntries, persistence } = config;
106
106
  let apps = null;
107
107
  let mountPath = null;
@@ -214,9 +214,9 @@ function createEmulateHandler(config) {
214
214
  DELETE: handler
215
215
  };
216
216
  }
217
- function withEmulate(nextConfig, options) {
217
+ function addApiEmulatorTracing(nextConfig, options, defaultRoutePrefix) {
218
218
  const config = nextConfig;
219
- const prefix = options?.routePrefix ?? "/emulate";
219
+ const prefix = options?.routePrefix ?? defaultRoutePrefix;
220
220
  const routePattern = `${prefix}/**`;
221
221
  const fontGlob = "./node_modules/@api-emulator/core/dist/fonts/**";
222
222
  const topLevel = { ...config.outputFileTracingIncludes ?? {} };
@@ -226,8 +226,11 @@ function withEmulate(nextConfig, options) {
226
226
  }
227
227
  return { ...config, outputFileTracingIncludes: topLevel };
228
228
  }
229
+ function withApiEmulator(nextConfig, options) {
230
+ return addApiEmulatorTracing(nextConfig, options, "/api-emulator");
231
+ }
229
232
  export {
230
- createEmulateHandler,
231
- withEmulate
233
+ createApiEmulatorHandler,
234
+ withApiEmulator
232
235
  };
233
236
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {\n createServer,\n debug,\n serializeTokenMap,\n restoreTokenMap,\n type ServicePlugin,\n type Store,\n type TokenMap,\n type TokenEntry,\n type StoreSnapshot,\n type PersistenceAdapter,\n type AppKeyResolver,\n type WebhookDispatcher,\n} from \"@api-emulator/core\";\n\nexport type { PersistenceAdapter } from \"@api-emulator/core\";\n\nexport interface EmulatorModule {\n plugin?: ServicePlugin;\n default?: ServicePlugin;\n seedFromConfig?(store: Store, baseUrl: string, config: unknown, webhooks?: WebhookDispatcher): void;\n createAppKeyResolver?(store: Store): AppKeyResolver;\n}\n\ninterface EmulatorEntry {\n emulator: EmulatorModule;\n seed?: Record<string, unknown>;\n}\n\nexport interface EmulateHandlerConfig {\n services: Record<string, EmulatorEntry>;\n persistence?: PersistenceAdapter;\n}\n\ninterface Fetchable {\n fetch(request: Request, ...rest: unknown[]): Response | Promise<Response>;\n}\n\ninterface ServiceApp {\n hono: Fetchable;\n store: Store;\n tokenMap: TokenMap;\n plugin: ServicePlugin;\n webhooks: WebhookDispatcher;\n}\n\ninterface FullSnapshot {\n store: StoreSnapshot;\n tokens: Record<string, TokenEntry[]>;\n}\n\ntype NextRequest = Request;\ntype NextResponse = Response;\ntype RouteHandler = (req: NextRequest, ctx: { params: Promise<{ path: string[] }> }) => Promise<NextResponse>;\n\nconst MUTATING_METHODS = new Set([\"POST\", \"PUT\", \"PATCH\", \"DELETE\"]);\n\nfunction resolvePlugin(mod: EmulatorModule): ServicePlugin {\n const plugin = mod.plugin ?? mod.default;\n if (!plugin) {\n throw new Error(\"Emulator module must export `plugin` or a default export implementing ServicePlugin\");\n }\n return plugin;\n}\n\nfunction takeSnapshot(apps: Map<string, ServiceApp>): FullSnapshot {\n const mergedStore: StoreSnapshot = { collections: {}, data: {} };\n const tokens: Record<string, TokenEntry[]> = {};\n\n for (const [name, sa] of apps) {\n const snap = sa.store.snapshot();\n for (const [colName, colSnap] of Object.entries(snap.collections)) {\n mergedStore.collections[`${name}:${colName}`] = colSnap;\n }\n for (const [key, val] of Object.entries(snap.data)) {\n mergedStore.data[`${name}:${key}`] = val;\n }\n tokens[name] = serializeTokenMap(sa.tokenMap);\n }\n\n return { store: mergedStore, tokens };\n}\n\nfunction restoreFromSnapshot(apps: Map<string, ServiceApp>, snapshot: FullSnapshot): void {\n const storesByName = new Map<string, StoreSnapshot>();\n for (const [qualifiedName, colSnap] of Object.entries(snapshot.store.collections)) {\n const sepIdx = qualifiedName.indexOf(\":\");\n const name = qualifiedName.slice(0, sepIdx);\n const colName = qualifiedName.slice(sepIdx + 1);\n if (!storesByName.has(name)) {\n storesByName.set(name, { collections: {}, data: {} });\n }\n storesByName.get(name)!.collections[colName] = colSnap;\n }\n for (const [qualifiedKey, val] of Object.entries(snapshot.store.data)) {\n const sepIdx = qualifiedKey.indexOf(\":\");\n const name = qualifiedKey.slice(0, sepIdx);\n const dataKey = qualifiedKey.slice(sepIdx + 1);\n if (!storesByName.has(name)) {\n storesByName.set(name, { collections: {}, data: {} });\n }\n storesByName.get(name)!.data[dataKey] = val;\n }\n\n for (const [name, sa] of apps) {\n const snap = storesByName.get(name);\n if (snap) {\n sa.store.restore(snap);\n }\n restoreTokenMap(sa.tokenMap, snapshot.tokens[name] ?? []);\n }\n}\n\nfunction detectPrefix(url: string, pathSegments: string[]): string {\n const parsed = new URL(url);\n const fullPath = parsed.pathname;\n const restPath = \"/\" + pathSegments.join(\"/\");\n const idx = fullPath.lastIndexOf(restPath);\n if (idx > 0) {\n return fullPath.slice(0, idx);\n }\n throw new Error(`Could not detect mount path from URL: ${url}`);\n}\n\nasync function rewriteResponse(response: Response, servicePrefix: string): Promise<Response> {\n const contentType = response.headers.get(\"Content-Type\") ?? \"\";\n const location = response.headers.get(\"Location\");\n const isHtml = contentType.includes(\"text/html\");\n const locationChanged = location != null && location.startsWith(\"/\");\n\n if (!isHtml) {\n if (!locationChanged) return response;\n const headers = new Headers(response.headers);\n headers.set(\"Location\", servicePrefix + location);\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n }\n\n let html = await response.text();\n\n // Skip paths already carrying the service prefix to avoid double-prefixing\n // (e.g., redirects that already went through rewriting).\n html = html.replace(/(action|href)=\"(\\/[^\"]*?)\"/g, (_match, attr, path) => {\n if (path.startsWith(servicePrefix)) return `${attr}=\"${path}\"`;\n return `${attr}=\"${servicePrefix}${path}\"`;\n });\n\n html = html.replace(/url\\('(\\/[^']*?)'\\)/g, (_match, path) => {\n if (path.startsWith(servicePrefix)) return `url('${path}')`;\n return `url('${servicePrefix}${path}')`;\n });\n\n const headers = new Headers(response.headers);\n if (locationChanged) {\n headers.set(\"Location\", servicePrefix + location);\n }\n headers.delete(\"Content-Length\");\n\n return new Response(html, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n}\n\nexport function createEmulateHandler(config: EmulateHandlerConfig) {\n const { services: serviceEntries, persistence } = config;\n\n let apps: Map<string, ServiceApp> | null = null;\n let mountPath: string | null = null;\n let initPromise: Promise<void> | null = null;\n let pendingSave: Promise<void> = Promise.resolve();\n\n function enqueueSave(): void {\n if (!persistence || !apps) return;\n pendingSave = pendingSave.then(async () => {\n if (!apps) return;\n const snapshot = takeSnapshot(apps);\n const json = JSON.stringify(snapshot);\n try {\n await persistence.save(json);\n } catch (err) {\n debug(\"persistence\", \"save failed: %o\", err);\n }\n });\n }\n\n async function initApps(origin: string, mountPath: string): Promise<Map<string, ServiceApp>> {\n const serviceApps = new Map<string, ServiceApp>();\n\n for (const [name, entry] of Object.entries(serviceEntries)) {\n const plugin = resolvePlugin(entry.emulator);\n const servicePrefix = `${mountPath}/${name}`;\n const baseUrl = `${origin}${servicePrefix}`;\n\n let appKeyResolver: AppKeyResolver | undefined;\n const { app, store, tokenMap, webhooks } = createServer(plugin, {\n baseUrl,\n appKeyResolver: entry.emulator.createAppKeyResolver ? (appId) => appKeyResolver!(appId) : undefined,\n });\n\n if (entry.emulator.createAppKeyResolver) {\n appKeyResolver = entry.emulator.createAppKeyResolver(store);\n }\n\n serviceApps.set(name, { hono: app, store, tokenMap, plugin, webhooks });\n }\n\n let restored = false;\n if (persistence) {\n const raw = await persistence.load();\n if (raw) {\n try {\n const snapshot = JSON.parse(raw) as FullSnapshot;\n restoreFromSnapshot(serviceApps, snapshot);\n restored = true;\n } catch {\n // Corrupted data, fall through to seeding\n }\n }\n }\n\n if (!restored) {\n for (const [name, entry] of Object.entries(serviceEntries)) {\n const sa = serviceApps.get(name)!;\n const servicePrefix = `${mountPath}/${name}`;\n const baseUrl = `${origin}${servicePrefix}`;\n sa.plugin.seed?.(sa.store, baseUrl);\n if (entry.seed && entry.emulator.seedFromConfig) {\n entry.emulator.seedFromConfig(sa.store, baseUrl, entry.seed, sa.webhooks);\n }\n }\n if (persistence) {\n enqueueSave();\n }\n }\n\n return serviceApps;\n }\n\n async function ensureInit(req: Request, pathSegments: string[]): Promise<Map<string, ServiceApp>> {\n if (apps) return apps;\n if (!initPromise) {\n const url = new URL(req.url);\n const origin = url.origin;\n mountPath = detectPrefix(req.url, pathSegments);\n initPromise = initApps(origin, mountPath).then((result) => {\n apps = result;\n });\n }\n await initPromise;\n return apps!;\n }\n\n async function handleRequest(req: NextRequest, ctx: { params: Promise<{ path: string[] }> }): Promise<NextResponse> {\n const { path: pathSegments } = await ctx.params;\n const serviceApps = await ensureInit(req, pathSegments);\n\n if (pathSegments.length === 0) {\n return new Response(\"Not found\", { status: 404 });\n }\n\n const serviceName = pathSegments[0];\n const sa = serviceApps.get(serviceName);\n if (!sa) {\n return new Response(`Unknown service: ${serviceName}`, { status: 404 });\n }\n\n const restPath = \"/\" + pathSegments.slice(1).join(\"/\");\n const url = new URL(req.url);\n const strippedUrl = new URL(restPath + url.search, url.origin);\n\n const strippedReq = new Request(strippedUrl.toString(), {\n method: req.method,\n headers: req.headers,\n body: req.body,\n duplex: \"half\",\n } as RequestInit & { duplex: string });\n\n let response = await sa.hono.fetch(strippedReq);\n\n const servicePrefix = `${mountPath!}/${serviceName}`;\n response = await rewriteResponse(response, servicePrefix);\n\n if (persistence && MUTATING_METHODS.has(req.method)) {\n enqueueSave();\n }\n\n return response;\n }\n\n const handler: RouteHandler = handleRequest;\n\n return {\n GET: handler,\n POST: handler,\n PUT: handler,\n PATCH: handler,\n DELETE: handler,\n };\n}\n\nexport function withEmulate<T>(nextConfig: T, options?: { routePrefix?: string }): T {\n const config = nextConfig as Record<string, unknown>;\n const prefix = options?.routePrefix ?? \"/emulate\";\n const routePattern = `${prefix}/**`;\n const fontGlob = \"./node_modules/@api-emulator/core/dist/fonts/**\";\n\n const topLevel = { ...((config.outputFileTracingIncludes as Record<string, string[]> | undefined) ?? {}) };\n const existing = topLevel[routePattern] ?? [];\n if (!existing.includes(fontGlob)) {\n topLevel[routePattern] = [...existing, fontGlob];\n }\n\n return { ...config, outputFileTracingIncludes: topLevel } as T;\n}\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OASK;AA0CP,IAAM,mBAAmB,oBAAI,IAAI,CAAC,QAAQ,OAAO,SAAS,QAAQ,CAAC;AAEnE,SAAS,cAAc,KAAoC;AACzD,QAAM,SAAS,IAAI,UAAU,IAAI;AACjC,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,qFAAqF;AAAA,EACvG;AACA,SAAO;AACT;AAEA,SAAS,aAAa,MAA6C;AACjE,QAAM,cAA6B,EAAE,aAAa,CAAC,GAAG,MAAM,CAAC,EAAE;AAC/D,QAAM,SAAuC,CAAC;AAE9C,aAAW,CAAC,MAAM,EAAE,KAAK,MAAM;AAC7B,UAAM,OAAO,GAAG,MAAM,SAAS;AAC/B,eAAW,CAAC,SAAS,OAAO,KAAK,OAAO,QAAQ,KAAK,WAAW,GAAG;AACjE,kBAAY,YAAY,GAAG,IAAI,IAAI,OAAO,EAAE,IAAI;AAAA,IAClD;AACA,eAAW,CAAC,KAAK,GAAG,KAAK,OAAO,QAAQ,KAAK,IAAI,GAAG;AAClD,kBAAY,KAAK,GAAG,IAAI,IAAI,GAAG,EAAE,IAAI;AAAA,IACvC;AACA,WAAO,IAAI,IAAI,kBAAkB,GAAG,QAAQ;AAAA,EAC9C;AAEA,SAAO,EAAE,OAAO,aAAa,OAAO;AACtC;AAEA,SAAS,oBAAoB,MAA+B,UAA8B;AACxF,QAAM,eAAe,oBAAI,IAA2B;AACpD,aAAW,CAAC,eAAe,OAAO,KAAK,OAAO,QAAQ,SAAS,MAAM,WAAW,GAAG;AACjF,UAAM,SAAS,cAAc,QAAQ,GAAG;AACxC,UAAM,OAAO,cAAc,MAAM,GAAG,MAAM;AAC1C,UAAM,UAAU,cAAc,MAAM,SAAS,CAAC;AAC9C,QAAI,CAAC,aAAa,IAAI,IAAI,GAAG;AAC3B,mBAAa,IAAI,MAAM,EAAE,aAAa,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC;AAAA,IACtD;AACA,iBAAa,IAAI,IAAI,EAAG,YAAY,OAAO,IAAI;AAAA,EACjD;AACA,aAAW,CAAC,cAAc,GAAG,KAAK,OAAO,QAAQ,SAAS,MAAM,IAAI,GAAG;AACrE,UAAM,SAAS,aAAa,QAAQ,GAAG;AACvC,UAAM,OAAO,aAAa,MAAM,GAAG,MAAM;AACzC,UAAM,UAAU,aAAa,MAAM,SAAS,CAAC;AAC7C,QAAI,CAAC,aAAa,IAAI,IAAI,GAAG;AAC3B,mBAAa,IAAI,MAAM,EAAE,aAAa,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC;AAAA,IACtD;AACA,iBAAa,IAAI,IAAI,EAAG,KAAK,OAAO,IAAI;AAAA,EAC1C;AAEA,aAAW,CAAC,MAAM,EAAE,KAAK,MAAM;AAC7B,UAAM,OAAO,aAAa,IAAI,IAAI;AAClC,QAAI,MAAM;AACR,SAAG,MAAM,QAAQ,IAAI;AAAA,IACvB;AACA,oBAAgB,GAAG,UAAU,SAAS,OAAO,IAAI,KAAK,CAAC,CAAC;AAAA,EAC1D;AACF;AAEA,SAAS,aAAa,KAAa,cAAgC;AACjE,QAAM,SAAS,IAAI,IAAI,GAAG;AAC1B,QAAM,WAAW,OAAO;AACxB,QAAM,WAAW,MAAM,aAAa,KAAK,GAAG;AAC5C,QAAM,MAAM,SAAS,YAAY,QAAQ;AACzC,MAAI,MAAM,GAAG;AACX,WAAO,SAAS,MAAM,GAAG,GAAG;AAAA,EAC9B;AACA,QAAM,IAAI,MAAM,yCAAyC,GAAG,EAAE;AAChE;AAEA,eAAe,gBAAgB,UAAoB,eAA0C;AAC3F,QAAM,cAAc,SAAS,QAAQ,IAAI,cAAc,KAAK;AAC5D,QAAM,WAAW,SAAS,QAAQ,IAAI,UAAU;AAChD,QAAM,SAAS,YAAY,SAAS,WAAW;AAC/C,QAAM,kBAAkB,YAAY,QAAQ,SAAS,WAAW,GAAG;AAEnE,MAAI,CAAC,QAAQ;AACX,QAAI,CAAC,gBAAiB,QAAO;AAC7B,UAAMA,WAAU,IAAI,QAAQ,SAAS,OAAO;AAC5C,IAAAA,SAAQ,IAAI,YAAY,gBAAgB,QAAQ;AAChD,WAAO,IAAI,SAAS,SAAS,MAAM;AAAA,MACjC,QAAQ,SAAS;AAAA,MACjB,YAAY,SAAS;AAAA,MACrB,SAAAA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,OAAO,MAAM,SAAS,KAAK;AAI/B,SAAO,KAAK,QAAQ,+BAA+B,CAAC,QAAQ,MAAM,SAAS;AACzE,QAAI,KAAK,WAAW,aAAa,EAAG,QAAO,GAAG,IAAI,KAAK,IAAI;AAC3D,WAAO,GAAG,IAAI,KAAK,aAAa,GAAG,IAAI;AAAA,EACzC,CAAC;AAED,SAAO,KAAK,QAAQ,wBAAwB,CAAC,QAAQ,SAAS;AAC5D,QAAI,KAAK,WAAW,aAAa,EAAG,QAAO,QAAQ,IAAI;AACvD,WAAO,QAAQ,aAAa,GAAG,IAAI;AAAA,EACrC,CAAC;AAED,QAAM,UAAU,IAAI,QAAQ,SAAS,OAAO;AAC5C,MAAI,iBAAiB;AACnB,YAAQ,IAAI,YAAY,gBAAgB,QAAQ;AAAA,EAClD;AACA,UAAQ,OAAO,gBAAgB;AAE/B,SAAO,IAAI,SAAS,MAAM;AAAA,IACxB,QAAQ,SAAS;AAAA,IACjB,YAAY,SAAS;AAAA,IACrB;AAAA,EACF,CAAC;AACH;AAEO,SAAS,qBAAqB,QAA8B;AACjE,QAAM,EAAE,UAAU,gBAAgB,YAAY,IAAI;AAElD,MAAI,OAAuC;AAC3C,MAAI,YAA2B;AAC/B,MAAI,cAAoC;AACxC,MAAI,cAA6B,QAAQ,QAAQ;AAEjD,WAAS,cAAoB;AAC3B,QAAI,CAAC,eAAe,CAAC,KAAM;AAC3B,kBAAc,YAAY,KAAK,YAAY;AACzC,UAAI,CAAC,KAAM;AACX,YAAM,WAAW,aAAa,IAAI;AAClC,YAAM,OAAO,KAAK,UAAU,QAAQ;AACpC,UAAI;AACF,cAAM,YAAY,KAAK,IAAI;AAAA,MAC7B,SAAS,KAAK;AACZ,cAAM,eAAe,mBAAmB,GAAG;AAAA,MAC7C;AAAA,IACF,CAAC;AAAA,EACH;AAEA,iBAAe,SAAS,QAAgBC,YAAqD;AAC3F,UAAM,cAAc,oBAAI,IAAwB;AAEhD,eAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,cAAc,GAAG;AAC1D,YAAM,SAAS,cAAc,MAAM,QAAQ;AAC3C,YAAM,gBAAgB,GAAGA,UAAS,IAAI,IAAI;AAC1C,YAAM,UAAU,GAAG,MAAM,GAAG,aAAa;AAEzC,UAAI;AACJ,YAAM,EAAE,KAAK,OAAO,UAAU,SAAS,IAAI,aAAa,QAAQ;AAAA,QAC9D;AAAA,QACA,gBAAgB,MAAM,SAAS,uBAAuB,CAAC,UAAU,eAAgB,KAAK,IAAI;AAAA,MAC5F,CAAC;AAED,UAAI,MAAM,SAAS,sBAAsB;AACvC,yBAAiB,MAAM,SAAS,qBAAqB,KAAK;AAAA,MAC5D;AAEA,kBAAY,IAAI,MAAM,EAAE,MAAM,KAAK,OAAO,UAAU,QAAQ,SAAS,CAAC;AAAA,IACxE;AAEA,QAAI,WAAW;AACf,QAAI,aAAa;AACf,YAAM,MAAM,MAAM,YAAY,KAAK;AACnC,UAAI,KAAK;AACP,YAAI;AACF,gBAAM,WAAW,KAAK,MAAM,GAAG;AAC/B,8BAAoB,aAAa,QAAQ;AACzC,qBAAW;AAAA,QACb,QAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,UAAU;AACb,iBAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,cAAc,GAAG;AAC1D,cAAM,KAAK,YAAY,IAAI,IAAI;AAC/B,cAAM,gBAAgB,GAAGA,UAAS,IAAI,IAAI;AAC1C,cAAM,UAAU,GAAG,MAAM,GAAG,aAAa;AACzC,WAAG,OAAO,OAAO,GAAG,OAAO,OAAO;AAClC,YAAI,MAAM,QAAQ,MAAM,SAAS,gBAAgB;AAC/C,gBAAM,SAAS,eAAe,GAAG,OAAO,SAAS,MAAM,MAAM,GAAG,QAAQ;AAAA,QAC1E;AAAA,MACF;AACA,UAAI,aAAa;AACf,oBAAY;AAAA,MACd;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,iBAAe,WAAW,KAAc,cAA0D;AAChG,QAAI,KAAM,QAAO;AACjB,QAAI,CAAC,aAAa;AAChB,YAAM,MAAM,IAAI,IAAI,IAAI,GAAG;AAC3B,YAAM,SAAS,IAAI;AACnB,kBAAY,aAAa,IAAI,KAAK,YAAY;AAC9C,oBAAc,SAAS,QAAQ,SAAS,EAAE,KAAK,CAAC,WAAW;AACzD,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AACA,UAAM;AACN,WAAO;AAAA,EACT;AAEA,iBAAe,cAAc,KAAkB,KAAqE;AAClH,UAAM,EAAE,MAAM,aAAa,IAAI,MAAM,IAAI;AACzC,UAAM,cAAc,MAAM,WAAW,KAAK,YAAY;AAEtD,QAAI,aAAa,WAAW,GAAG;AAC7B,aAAO,IAAI,SAAS,aAAa,EAAE,QAAQ,IAAI,CAAC;AAAA,IAClD;AAEA,UAAM,cAAc,aAAa,CAAC;AAClC,UAAM,KAAK,YAAY,IAAI,WAAW;AACtC,QAAI,CAAC,IAAI;AACP,aAAO,IAAI,SAAS,oBAAoB,WAAW,IAAI,EAAE,QAAQ,IAAI,CAAC;AAAA,IACxE;AAEA,UAAM,WAAW,MAAM,aAAa,MAAM,CAAC,EAAE,KAAK,GAAG;AACrD,UAAM,MAAM,IAAI,IAAI,IAAI,GAAG;AAC3B,UAAM,cAAc,IAAI,IAAI,WAAW,IAAI,QAAQ,IAAI,MAAM;AAE7D,UAAM,cAAc,IAAI,QAAQ,YAAY,SAAS,GAAG;AAAA,MACtD,QAAQ,IAAI;AAAA,MACZ,SAAS,IAAI;AAAA,MACb,MAAM,IAAI;AAAA,MACV,QAAQ;AAAA,IACV,CAAqC;AAErC,QAAI,WAAW,MAAM,GAAG,KAAK,MAAM,WAAW;AAE9C,UAAM,gBAAgB,GAAG,SAAU,IAAI,WAAW;AAClD,eAAW,MAAM,gBAAgB,UAAU,aAAa;AAExD,QAAI,eAAe,iBAAiB,IAAI,IAAI,MAAM,GAAG;AACnD,kBAAY;AAAA,IACd;AAEA,WAAO;AAAA,EACT;AAEA,QAAM,UAAwB;AAE9B,SAAO;AAAA,IACL,KAAK;AAAA,IACL,MAAM;AAAA,IACN,KAAK;AAAA,IACL,OAAO;AAAA,IACP,QAAQ;AAAA,EACV;AACF;AAEO,SAAS,YAAe,YAAe,SAAuC;AACnF,QAAM,SAAS;AACf,QAAM,SAAS,SAAS,eAAe;AACvC,QAAM,eAAe,GAAG,MAAM;AAC9B,QAAM,WAAW;AAEjB,QAAM,WAAW,EAAE,GAAK,OAAO,6BAAsE,CAAC,EAAG;AACzG,QAAM,WAAW,SAAS,YAAY,KAAK,CAAC;AAC5C,MAAI,CAAC,SAAS,SAAS,QAAQ,GAAG;AAChC,aAAS,YAAY,IAAI,CAAC,GAAG,UAAU,QAAQ;AAAA,EACjD;AAEA,SAAO,EAAE,GAAG,QAAQ,2BAA2B,SAAS;AAC1D;","names":["headers","mountPath"]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {\n createServer,\n debug,\n serializeTokenMap,\n restoreTokenMap,\n type ServicePlugin,\n type Store,\n type TokenMap,\n type TokenEntry,\n type StoreSnapshot,\n type PersistenceAdapter,\n type AppKeyResolver,\n type WebhookDispatcher,\n} from \"@api-emulator/core\";\n\nexport type { PersistenceAdapter } from \"@api-emulator/core\";\n\nexport interface EmulatorModule {\n plugin?: ServicePlugin;\n default?: ServicePlugin;\n seedFromConfig?(store: Store, baseUrl: string, config: unknown, webhooks?: WebhookDispatcher): void;\n createAppKeyResolver?(store: Store): AppKeyResolver;\n}\n\ninterface EmulatorEntry {\n emulator: EmulatorModule;\n seed?: Record<string, unknown>;\n}\n\nexport interface ApiEmulatorHandlerConfig {\n services: Record<string, EmulatorEntry>;\n persistence?: PersistenceAdapter;\n}\n\ninterface Fetchable {\n fetch(request: Request, ...rest: unknown[]): Response | Promise<Response>;\n}\n\ninterface ServiceApp {\n hono: Fetchable;\n store: Store;\n tokenMap: TokenMap;\n plugin: ServicePlugin;\n webhooks: WebhookDispatcher;\n}\n\ninterface FullSnapshot {\n store: StoreSnapshot;\n tokens: Record<string, TokenEntry[]>;\n}\n\ntype NextRequest = Request;\ntype NextResponse = Response;\ntype RouteHandler = (req: NextRequest, ctx: { params: Promise<{ path: string[] }> }) => Promise<NextResponse>;\n\nconst MUTATING_METHODS = new Set([\"POST\", \"PUT\", \"PATCH\", \"DELETE\"]);\n\nfunction resolvePlugin(mod: EmulatorModule): ServicePlugin {\n const plugin = mod.plugin ?? mod.default;\n if (!plugin) {\n throw new Error(\"Emulator module must export `plugin` or a default export implementing ServicePlugin\");\n }\n return plugin;\n}\n\nfunction takeSnapshot(apps: Map<string, ServiceApp>): FullSnapshot {\n const mergedStore: StoreSnapshot = { collections: {}, data: {} };\n const tokens: Record<string, TokenEntry[]> = {};\n\n for (const [name, sa] of apps) {\n const snap = sa.store.snapshot();\n for (const [colName, colSnap] of Object.entries(snap.collections)) {\n mergedStore.collections[`${name}:${colName}`] = colSnap;\n }\n for (const [key, val] of Object.entries(snap.data)) {\n mergedStore.data[`${name}:${key}`] = val;\n }\n tokens[name] = serializeTokenMap(sa.tokenMap);\n }\n\n return { store: mergedStore, tokens };\n}\n\nfunction restoreFromSnapshot(apps: Map<string, ServiceApp>, snapshot: FullSnapshot): void {\n const storesByName = new Map<string, StoreSnapshot>();\n for (const [qualifiedName, colSnap] of Object.entries(snapshot.store.collections)) {\n const sepIdx = qualifiedName.indexOf(\":\");\n const name = qualifiedName.slice(0, sepIdx);\n const colName = qualifiedName.slice(sepIdx + 1);\n if (!storesByName.has(name)) {\n storesByName.set(name, { collections: {}, data: {} });\n }\n storesByName.get(name)!.collections[colName] = colSnap;\n }\n for (const [qualifiedKey, val] of Object.entries(snapshot.store.data)) {\n const sepIdx = qualifiedKey.indexOf(\":\");\n const name = qualifiedKey.slice(0, sepIdx);\n const dataKey = qualifiedKey.slice(sepIdx + 1);\n if (!storesByName.has(name)) {\n storesByName.set(name, { collections: {}, data: {} });\n }\n storesByName.get(name)!.data[dataKey] = val;\n }\n\n for (const [name, sa] of apps) {\n const snap = storesByName.get(name);\n if (snap) {\n sa.store.restore(snap);\n }\n restoreTokenMap(sa.tokenMap, snapshot.tokens[name] ?? []);\n }\n}\n\nfunction detectPrefix(url: string, pathSegments: string[]): string {\n const parsed = new URL(url);\n const fullPath = parsed.pathname;\n const restPath = \"/\" + pathSegments.join(\"/\");\n const idx = fullPath.lastIndexOf(restPath);\n if (idx > 0) {\n return fullPath.slice(0, idx);\n }\n throw new Error(`Could not detect mount path from URL: ${url}`);\n}\n\nasync function rewriteResponse(response: Response, servicePrefix: string): Promise<Response> {\n const contentType = response.headers.get(\"Content-Type\") ?? \"\";\n const location = response.headers.get(\"Location\");\n const isHtml = contentType.includes(\"text/html\");\n const locationChanged = location != null && location.startsWith(\"/\");\n\n if (!isHtml) {\n if (!locationChanged) return response;\n const headers = new Headers(response.headers);\n headers.set(\"Location\", servicePrefix + location);\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n }\n\n let html = await response.text();\n\n // Skip paths already carrying the service prefix to avoid double-prefixing\n // (e.g., redirects that already went through rewriting).\n html = html.replace(/(action|href)=\"(\\/[^\"]*?)\"/g, (_match, attr, path) => {\n if (path.startsWith(servicePrefix)) return `${attr}=\"${path}\"`;\n return `${attr}=\"${servicePrefix}${path}\"`;\n });\n\n html = html.replace(/url\\('(\\/[^']*?)'\\)/g, (_match, path) => {\n if (path.startsWith(servicePrefix)) return `url('${path}')`;\n return `url('${servicePrefix}${path}')`;\n });\n\n const headers = new Headers(response.headers);\n if (locationChanged) {\n headers.set(\"Location\", servicePrefix + location);\n }\n headers.delete(\"Content-Length\");\n\n return new Response(html, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n}\n\nexport function createApiEmulatorHandler(config: ApiEmulatorHandlerConfig) {\n const { services: serviceEntries, persistence } = config;\n\n let apps: Map<string, ServiceApp> | null = null;\n let mountPath: string | null = null;\n let initPromise: Promise<void> | null = null;\n let pendingSave: Promise<void> = Promise.resolve();\n\n function enqueueSave(): void {\n if (!persistence || !apps) return;\n pendingSave = pendingSave.then(async () => {\n if (!apps) return;\n const snapshot = takeSnapshot(apps);\n const json = JSON.stringify(snapshot);\n try {\n await persistence.save(json);\n } catch (err) {\n debug(\"persistence\", \"save failed: %o\", err);\n }\n });\n }\n\n async function initApps(origin: string, mountPath: string): Promise<Map<string, ServiceApp>> {\n const serviceApps = new Map<string, ServiceApp>();\n\n for (const [name, entry] of Object.entries(serviceEntries)) {\n const plugin = resolvePlugin(entry.emulator);\n const servicePrefix = `${mountPath}/${name}`;\n const baseUrl = `${origin}${servicePrefix}`;\n\n let appKeyResolver: AppKeyResolver | undefined;\n const { app, store, tokenMap, webhooks } = createServer(plugin, {\n baseUrl,\n appKeyResolver: entry.emulator.createAppKeyResolver ? (appId) => appKeyResolver!(appId) : undefined,\n });\n\n if (entry.emulator.createAppKeyResolver) {\n appKeyResolver = entry.emulator.createAppKeyResolver(store);\n }\n\n serviceApps.set(name, { hono: app, store, tokenMap, plugin, webhooks });\n }\n\n let restored = false;\n if (persistence) {\n const raw = await persistence.load();\n if (raw) {\n try {\n const snapshot = JSON.parse(raw) as FullSnapshot;\n restoreFromSnapshot(serviceApps, snapshot);\n restored = true;\n } catch {\n // Corrupted data, fall through to seeding\n }\n }\n }\n\n if (!restored) {\n for (const [name, entry] of Object.entries(serviceEntries)) {\n const sa = serviceApps.get(name)!;\n const servicePrefix = `${mountPath}/${name}`;\n const baseUrl = `${origin}${servicePrefix}`;\n sa.plugin.seed?.(sa.store, baseUrl);\n if (entry.seed && entry.emulator.seedFromConfig) {\n entry.emulator.seedFromConfig(sa.store, baseUrl, entry.seed, sa.webhooks);\n }\n }\n if (persistence) {\n enqueueSave();\n }\n }\n\n return serviceApps;\n }\n\n async function ensureInit(req: Request, pathSegments: string[]): Promise<Map<string, ServiceApp>> {\n if (apps) return apps;\n if (!initPromise) {\n const url = new URL(req.url);\n const origin = url.origin;\n mountPath = detectPrefix(req.url, pathSegments);\n initPromise = initApps(origin, mountPath).then((result) => {\n apps = result;\n });\n }\n await initPromise;\n return apps!;\n }\n\n async function handleRequest(req: NextRequest, ctx: { params: Promise<{ path: string[] }> }): Promise<NextResponse> {\n const { path: pathSegments } = await ctx.params;\n const serviceApps = await ensureInit(req, pathSegments);\n\n if (pathSegments.length === 0) {\n return new Response(\"Not found\", { status: 404 });\n }\n\n const serviceName = pathSegments[0];\n const sa = serviceApps.get(serviceName);\n if (!sa) {\n return new Response(`Unknown service: ${serviceName}`, { status: 404 });\n }\n\n const restPath = \"/\" + pathSegments.slice(1).join(\"/\");\n const url = new URL(req.url);\n const strippedUrl = new URL(restPath + url.search, url.origin);\n\n const strippedReq = new Request(strippedUrl.toString(), {\n method: req.method,\n headers: req.headers,\n body: req.body,\n duplex: \"half\",\n } as RequestInit & { duplex: string });\n\n let response = await sa.hono.fetch(strippedReq);\n\n const servicePrefix = `${mountPath!}/${serviceName}`;\n response = await rewriteResponse(response, servicePrefix);\n\n if (persistence && MUTATING_METHODS.has(req.method)) {\n enqueueSave();\n }\n\n return response;\n }\n\n const handler: RouteHandler = handleRequest;\n\n return {\n GET: handler,\n POST: handler,\n PUT: handler,\n PATCH: handler,\n DELETE: handler,\n };\n}\n\nfunction addApiEmulatorTracing<T>(\n nextConfig: T,\n options: { routePrefix?: string } | undefined,\n defaultRoutePrefix: string,\n): T {\n const config = nextConfig as Record<string, unknown>;\n const prefix = options?.routePrefix ?? defaultRoutePrefix;\n const routePattern = `${prefix}/**`;\n const fontGlob = \"./node_modules/@api-emulator/core/dist/fonts/**\";\n\n const topLevel = { ...((config.outputFileTracingIncludes as Record<string, string[]> | undefined) ?? {}) };\n const existing = topLevel[routePattern] ?? [];\n if (!existing.includes(fontGlob)) {\n topLevel[routePattern] = [...existing, fontGlob];\n }\n\n return { ...config, outputFileTracingIncludes: topLevel } as T;\n}\n\nexport function withApiEmulator<T>(nextConfig: T, options?: { routePrefix?: string }): T {\n return addApiEmulatorTracing(nextConfig, options, \"/api-emulator\");\n}\n"],"mappings":"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","names":["headers","mountPath"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@api-emulator/adapter-next",
3
- "version": "0.5.2",
3
+ "version": "0.6.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -36,7 +36,7 @@
36
36
  "lint": "eslint src"
37
37
  },
38
38
  "dependencies": {
39
- "@api-emulator/core": "0.5.2"
39
+ "@api-emulator/core": "0.6.0"
40
40
  },
41
41
  "devDependencies": {
42
42
  "tsup": "^8",