@emulators/adapter-next 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/dist/index.js CHANGED
@@ -134,7 +134,7 @@ function createEmulateHandler(config) {
134
134
  if (entry.emulator.createAppKeyResolver) {
135
135
  appKeyResolver = entry.emulator.createAppKeyResolver(store);
136
136
  }
137
- serviceApps.set(name, { hono: app, store, tokenMap, plugin, webhooks });
137
+ serviceApps.set(name, { app, store, tokenMap, plugin, webhooks });
138
138
  }
139
139
  let restored = false;
140
140
  if (persistence) {
@@ -197,7 +197,7 @@ function createEmulateHandler(config) {
197
197
  body: req.body,
198
198
  duplex: "half"
199
199
  });
200
- let response = await sa.hono.fetch(strippedReq);
200
+ let response = await sa.app.fetch(strippedReq);
201
201
  const servicePrefix = `${mountPath}/${serviceName}`;
202
202
  response = await rewriteResponse(response, servicePrefix);
203
203
  if (persistence && MUTATING_METHODS.has(req.method)) {
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 \"@emulators/core\";\n\nexport type { PersistenceAdapter } from \"@emulators/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/@emulators/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":"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","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 \"@emulators/core\";\n\nexport type { PersistenceAdapter } from \"@emulators/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 app: 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, { 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.app.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/@emulators/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":"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","names":["headers","mountPath"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@emulators/adapter-next",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -28,7 +28,7 @@
28
28
  "dist"
29
29
  ],
30
30
  "dependencies": {
31
- "@emulators/core": "0.5.0"
31
+ "@emulators/core": "0.6.0"
32
32
  },
33
33
  "devDependencies": {
34
34
  "tsup": "^8",