@parlor/server 0.3.0 → 0.3.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../src/cors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,KAAK,OAAO,EAAc,MAAM,IAAI,CAAC;AAI9C,OAAO,EAAE,aAAa,EAAE,CAAC;AAIzB,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GAAG,SAAS,CAAC;CAC7D;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,KAAK,GAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAO,WAMzC;AAED,wBAAgB,cAAc,CAAC,MAAM,GAAE,UAAe,WAErC,OAAO,2CAWvB"}
1
+ {"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../src/cors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7D,OAAO,EAAE,KAAK,OAAO,EAAc,MAAM,IAAI,CAAC;AAI9C,OAAO,EAAE,aAAa,EAAE,CAAC;AAIzB,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GAAG,SAAS,CAAC;CAC7D;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,KAAK,GAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAO,WAMzC;AAED,wBAAgB,cAAc,CAAC,MAAM,GAAE,UAAe,WAErC,OAAO,2CAiBvB"}
package/dist/cors.js CHANGED
@@ -1,4 +1,4 @@
1
- import { SHELL_ORIGINS } from "@parlor/core";
1
+ import { REFRESH_HEADER, SHELL_ORIGINS } from "@parlor/core";
2
2
  import { handleCors } from "h3";
3
3
  import { CLIENT_HEADER, SESSION_TOKEN_HEADER, SOURCE_HEADER } from "./protocol.js";
4
4
  export { SHELL_ORIGINS };
@@ -14,7 +14,13 @@ export function corsMiddleware(config = {}) {
14
14
  const preflight = handleCors(event, {
15
15
  origin: (origin) => isAllowedOrigin(origin, extra),
16
16
  methods: ["GET", "POST", "OPTIONS"],
17
- allowHeaders: ["content-type", "authorization", SOURCE_HEADER, CLIENT_HEADER],
17
+ allowHeaders: [
18
+ "content-type",
19
+ "authorization",
20
+ SOURCE_HEADER,
21
+ CLIENT_HEADER,
22
+ REFRESH_HEADER,
23
+ ],
18
24
  credentials: true,
19
25
  exposeHeaders: ["content-type", "content-length", SESSION_TOKEN_HEADER],
20
26
  preflight: { statusCode: 204 },
package/dist/cors.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cors.js","sourceRoot":"","sources":["../src/cors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAgB,UAAU,EAAE,MAAM,IAAI,CAAC;AAE9C,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnF,OAAO,EAAE,aAAa,EAAE,CAAC;AAEzB,MAAM,gBAAgB,GAAG,sDAAsD,CAAC;AAMhF,MAAM,UAAU,eAAe,CAC7B,MAAc,EACd,KAAK,GAAiC,EAAE;IAExC,IAAI,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IACjF,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CACzB,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAC/D,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAM,GAAe,EAAE;IACpD,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;IACnC,OAAO,CAAC,KAAc,EAAE,EAAE;QACxB,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,EAAE;YAClC,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,eAAe,CAAC,MAAM,EAAE,KAAK,CAAC;YAClD,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC;YACnC,YAAY,EAAE,CAAC,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,aAAa,CAAC;YAC7E,WAAW,EAAE,IAAI;YACjB,aAAa,EAAE,CAAC,cAAc,EAAE,gBAAgB,EAAE,oBAAoB,CAAC;YACvE,SAAS,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE;SAC/B,CAAC,CAAC;QACH,OAAO,SAAS,IAAI,SAAS,CAAC;IAChC,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import { SHELL_ORIGINS } from \"@parlor/core\";\nimport { type H3Event, handleCors } from \"h3\";\n\nimport { CLIENT_HEADER, SESSION_TOKEN_HEADER, SOURCE_HEADER } from \"./protocol.js\";\n\nexport { SHELL_ORIGINS };\n\nconst LOCAL_DEV_ORIGIN = /^https?:\\/\\/(localhost|127\\.0\\.0\\.1|\\[::1\\])(:\\d+)?$/;\n\nexport interface CorsConfig {\n readonly origins?: readonly (string | RegExp)[] | undefined;\n}\n\nexport function isAllowedOrigin(\n origin: string,\n extra: readonly (string | RegExp)[] = [],\n) {\n if (SHELL_ORIGINS.includes(origin) || LOCAL_DEV_ORIGIN.test(origin)) return true;\n return extra.some((rule) =>\n typeof rule === \"string\" ? rule === origin : rule.test(origin),\n );\n}\n\nexport function corsMiddleware(config: CorsConfig = {}) {\n const extra = config.origins ?? [];\n return (event: H3Event) => {\n const preflight = handleCors(event, {\n origin: (origin) => isAllowedOrigin(origin, extra),\n methods: [\"GET\", \"POST\", \"OPTIONS\"],\n allowHeaders: [\"content-type\", \"authorization\", SOURCE_HEADER, CLIENT_HEADER],\n credentials: true,\n exposeHeaders: [\"content-type\", \"content-length\", SESSION_TOKEN_HEADER],\n preflight: { statusCode: 204 },\n });\n return preflight || undefined;\n };\n}\n"]}
1
+ {"version":3,"file":"cors.js","sourceRoot":"","sources":["../src/cors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7D,OAAO,EAAgB,UAAU,EAAE,MAAM,IAAI,CAAC;AAE9C,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnF,OAAO,EAAE,aAAa,EAAE,CAAC;AAEzB,MAAM,gBAAgB,GAAG,sDAAsD,CAAC;AAMhF,MAAM,UAAU,eAAe,CAC7B,MAAc,EACd,KAAK,GAAiC,EAAE;IAExC,IAAI,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IACjF,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CACzB,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAC/D,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAM,GAAe,EAAE;IACpD,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;IACnC,OAAO,CAAC,KAAc,EAAE,EAAE;QACxB,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,EAAE;YAClC,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,eAAe,CAAC,MAAM,EAAE,KAAK,CAAC;YAClD,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC;YACnC,YAAY,EAAE;gBACZ,cAAc;gBACd,eAAe;gBACf,aAAa;gBACb,aAAa;gBACb,cAAc;aACf;YACD,WAAW,EAAE,IAAI;YACjB,aAAa,EAAE,CAAC,cAAc,EAAE,gBAAgB,EAAE,oBAAoB,CAAC;YACvE,SAAS,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE;SAC/B,CAAC,CAAC;QACH,OAAO,SAAS,IAAI,SAAS,CAAC;IAChC,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import { REFRESH_HEADER, SHELL_ORIGINS } from \"@parlor/core\";\nimport { type H3Event, handleCors } from \"h3\";\n\nimport { CLIENT_HEADER, SESSION_TOKEN_HEADER, SOURCE_HEADER } from \"./protocol.js\";\n\nexport { SHELL_ORIGINS };\n\nconst LOCAL_DEV_ORIGIN = /^https?:\\/\\/(localhost|127\\.0\\.0\\.1|\\[::1\\])(:\\d+)?$/;\n\nexport interface CorsConfig {\n readonly origins?: readonly (string | RegExp)[] | undefined;\n}\n\nexport function isAllowedOrigin(\n origin: string,\n extra: readonly (string | RegExp)[] = [],\n) {\n if (SHELL_ORIGINS.includes(origin) || LOCAL_DEV_ORIGIN.test(origin)) return true;\n return extra.some((rule) =>\n typeof rule === \"string\" ? rule === origin : rule.test(origin),\n );\n}\n\nexport function corsMiddleware(config: CorsConfig = {}) {\n const extra = config.origins ?? [];\n return (event: H3Event) => {\n const preflight = handleCors(event, {\n origin: (origin) => isAllowedOrigin(origin, extra),\n methods: [\"GET\", \"POST\", \"OPTIONS\"],\n allowHeaders: [\n \"content-type\",\n \"authorization\",\n SOURCE_HEADER,\n CLIENT_HEADER,\n REFRESH_HEADER,\n ],\n credentials: true,\n exposeHeaders: [\"content-type\", \"content-length\", SESSION_TOKEN_HEADER],\n preflight: { statusCode: 204 },\n });\n return preflight || undefined;\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"create-server.d.ts","sourceRoot":"","sources":["../src/create-server.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,cAAc,EAInB,KAAK,gBAAgB,EACtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAGL,KAAK,SAAS,EAEd,KAAK,YAAY,EAClB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EAML,KAAK,aAAa,EACnB,MAAM,qBAAqB,CAAC;AAK7B,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AAQ3D,OAAO,EAAE,KAAK,UAAU,EAAkB,MAAM,WAAW,CAAC;AAI5D,OAAO,KAAK,EAMV,YAAY,EACb,MAAM,aAAa,CAAC;AAErB,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAE9D,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IAC/C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9C;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,SAAS;IAChD,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;IACpC,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IAC3C;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IACzC,mFAAmF;IACnF,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,CAAC;IACvD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,GAAG,KAAK,GAAG,SAAS,CAAC;IAC/C,QAAQ,CAAC,QAAQ,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,GAAG,CAAC,EACT;QAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,GAC7E,KAAK,GACL,SAAS,CAAC;IACd,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,GAAG,KAAK,GAAG,SAAS,CAAC;IAChD,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,KAAK,GAAG,SAAS,CAAC;CACvD;AAKD,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC9E,QAAQ,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IACxD,QAAQ,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAmND,wBAAgB,YAAY,CAAC,CAAC,SAAS,SAAS,EAC9C,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,GACxB,eAAe,CA0RjB"}
1
+ {"version":3,"file":"create-server.d.ts","sourceRoot":"","sources":["../src/create-server.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,cAAc,EAInB,KAAK,gBAAgB,EACtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAGL,KAAK,SAAS,EAEd,KAAK,YAAY,EAGlB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EAML,KAAK,aAAa,EACnB,MAAM,qBAAqB,CAAC;AAK7B,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AAQ3D,OAAO,EAAE,KAAK,UAAU,EAAkB,MAAM,WAAW,CAAC;AAI5D,OAAO,KAAK,EAMV,YAAY,EACb,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAE9D,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IAC/C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9C;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,SAAS;IAChD,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;IACpC,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IAC3C;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IACzC,mFAAmF;IACnF,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,CAAC;IACvD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,GAAG,KAAK,GAAG,SAAS,CAAC;IAC/C,QAAQ,CAAC,QAAQ,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,GAAG,CAAC,EACT;QAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,GAC7E,KAAK,GACL,SAAS,CAAC;IACd,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,GAAG,KAAK,GAAG,SAAS,CAAC;IAChD,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,KAAK,GAAG,SAAS,CAAC;CACvD;AAKD,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC9E,QAAQ,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IACxD,QAAQ,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAoND,wBAAgB,YAAY,CAAC,CAAC,SAAS,SAAS,EAC9C,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,GACxB,eAAe,CA6SjB"}
@@ -1,6 +1,6 @@
1
1
  import { pagePattern, UNROUTED_HEADER } from "@parlor/agent-ui";
2
2
  import { createAgentUi, registerAgentUiRoutes, } from "@parlor/agent-ui/server";
3
- import { ActionError, ANONYMOUS, } from "@parlor/core";
3
+ import { ActionError, ANONYMOUS, decodeReadRequests, REFRESH_HEADER, } from "@parlor/core";
4
4
  import { ensureSyncTables, recordSyncEvent, registerSyncRoutes, SyncHub, } from "@parlor/sync/server";
5
5
  import { H3, readBody } from "h3";
6
6
  import { admits, requireAccess, requireSurface } from "./access.js";
@@ -12,6 +12,7 @@ import { devAuth } from "./dev-auth.js";
12
12
  import { createMcpHandler } from "./mcp.js";
13
13
  import { applyMigrations, checkMigrations } from "./migrations.js";
14
14
  import { DEFAULT_BASE_PATH, PROTOCOL_VERSION } from "./protocol.js";
15
+ import { refreshReads } from "./refresh.js";
15
16
  import { defaultScope } from "./scope.js";
16
17
  const STATUS_BY_CODE = {
17
18
  not_found: 404,
@@ -142,6 +143,7 @@ function gatedChannel(installed, channel) {
142
143
  return channel;
143
144
  return {
144
145
  event: channel.event,
146
+ hosts: channel.hosts,
145
147
  connect(connection) {
146
148
  let detach;
147
149
  let left = false;
@@ -273,11 +275,21 @@ export function createServer(options) {
273
275
  const input = await readBody(event).catch(() => {
274
276
  throw new ActionError("invalid_input", "Request body must be JSON");
275
277
  });
276
- const result = await runner.run(name, input, event.req, sourceOf(event.req), {
278
+ const source = sourceOf(event.req);
279
+ const run = (action, actionInput) => runner.run(action, actionInput, event.req, source, {
277
280
  surface: "actions",
278
281
  cursor: true,
279
282
  });
280
- return { data: result.data, tags: result.reads, cursor: result.cursor };
283
+ const result = await run(name, input);
284
+ const answer = { data: result.data, tags: result.reads, cursor: result.cursor };
285
+ const reads = decodeReadRequests(event.req.headers.get(REFRESH_HEADER));
286
+ if (!reads)
287
+ return answer;
288
+ const refreshed = await refreshReads(actions, reads, result.writes, async (action, actionInput) => {
289
+ const read = await run(action, actionInput);
290
+ return { data: read.data, tags: read.reads, cursor: read.cursor };
291
+ }, (error) => toActionError(error).toBody());
292
+ return { ...answer, writes: result.writes, refreshed };
281
293
  }
282
294
  catch (error) {
283
295
  return errorBody(event, error);
@@ -370,7 +382,9 @@ export function createServer(options) {
370
382
  const { principal } = caller;
371
383
  return {
372
384
  principal,
373
- channels: admits("channels", caller, callers.enforcing),
385
+ channels: admits("channels", caller, callers.enforcing)
386
+ ? true
387
+ : (channel) => principal.kind === "host" && channel.hosts === true,
374
388
  ...(auth && principal.kind !== "anonymous"
375
389
  ? { revoked: auth.revoked(principal) }
376
390
  : {}),
@@ -1 +1 @@
1
- {"version":3,"file":"create-server.js","sourceRoot":"","sources":["../src/create-server.ts"],"names":[],"mappings":"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","sourcesContent":["import { pagePattern, UNROUTED_HEADER } from \"@parlor/agent-ui\";\nimport {\n type AgentUiOptions,\n createAgentUi,\n registerAgentUiRoutes,\n type UiManifestInput,\n type UiManifestSource,\n} from \"@parlor/agent-ui/server\";\nimport {\n ActionError,\n type ActionErrorCode,\n type ActionMap,\n ANONYMOUS,\n type DataProvider,\n} from \"@parlor/core\";\nimport type { ActionRegistry } from \"@parlor/core/registry\";\nimport type { ServerChannel } from \"@parlor/sync\";\nimport {\n ensureSyncTables,\n recordSyncEvent,\n registerSyncRoutes,\n type SyncDatabase,\n SyncHub,\n type SyncTransport,\n} from \"@parlor/sync/server\";\nimport { H3, type H3Event, readBody } from \"h3\";\n\nimport { admits, requireAccess, requireSurface, type Surface } from \"./access.js\";\nimport { type ActionRunner, createActionRunner } from \"./actions.js\";\nimport { AuthFailure, type AuthProvider } from \"./auth.js\";\nimport {\n type Caller,\n type CallerResolver,\n clientOf,\n createCallerResolver,\n sourceOf,\n} from \"./caller.js\";\nimport { type CorsConfig, corsMiddleware } from \"./cors.js\";\nimport { devAuth } from \"./dev-auth.js\";\nimport { createMcpHandler } from \"./mcp.js\";\nimport { applyMigrations, checkMigrations } from \"./migrations.js\";\nimport type {\n ActionAudit,\n AnyPluginRoute,\n PluginCaller,\n PluginHost,\n PluginRuntime,\n ServerPlugin,\n} from \"./plugin.js\";\nimport { DEFAULT_BASE_PATH, type Manifest, PROTOCOL_VERSION } from \"./protocol.js\";\nimport { defaultScope, type ScopeResolver } from \"./scope.js\";\n\nexport interface SyncOptions {\n readonly transport?: SyncTransport | undefined;\n readonly pollIntervalMs?: number | undefined;\n}\n\nexport interface ServerOptions<T extends ActionMap> {\n readonly actions: ActionRegistry<T>;\n readonly scope?: ScopeResolver | undefined;\n /**\n * Without it every caller is anonymous, the action source is the `x-parlor-source`\n * header, and confirmations are a UX guard.\n */\n readonly auth?: AuthProvider | undefined;\n /** Framework features with their own tables and routes, installed after `auth`. */\n readonly plugins?: readonly ServerPlugin[] | undefined;\n readonly basePath?: string | undefined;\n readonly cors?: CorsConfig | false | undefined;\n readonly database?: DataProvider | undefined;\n readonly mcp?:\n | { readonly name?: string | undefined; readonly version?: string | undefined }\n | false\n | undefined;\n readonly sync?: SyncOptions | false | undefined;\n readonly agentUi?: AgentUiOptions | false | undefined;\n}\n\ntype ManifestSummary = Pick<Manifest, \"protocol\" | \"app\">;\ntype ManifestReply = Manifest | ManifestSummary | Response;\n\nexport interface FrameworkServer {\n /**\n * Hands the server the app's page routes, called by the host before the first request.\n * Throws when a page route would take a document request meant for an absolute route.\n */\n readonly installUiManifest?: ((source: UiManifestSource) => void) | undefined;\n readonly fetch: (request: Request) => Promise<Response>;\n readonly close: () => Promise<void>;\n}\n\nconst STATUS_BY_CODE = {\n not_found: 404,\n invalid_input: 400,\n declined: 403,\n confirmation_timeout: 504,\n confirmation_unavailable: 503,\n unauthenticated: 401,\n forbidden: 403,\n internal: 500,\n} as const satisfies Record<ActionErrorCode, number>;\n\nconst isAbort = (error: unknown) => error instanceof Error && error.name === \"AbortError\";\n\nfunction toActionError(error: unknown): ActionError {\n if (error instanceof ActionError) return error;\n if (error instanceof AuthFailure)\n return new ActionError(\"unauthenticated\", error.message);\n if (!isAbort(error)) console.error(\"[parlor] action failed:\", error);\n return new ActionError(\"internal\", \"Internal error\", { cause: error });\n}\n\nfunction errorBody(event: H3Event, error: unknown) {\n const actionError = toActionError(error);\n event.res.status = STATUS_BY_CODE[actionError.code];\n return actionError.toBody();\n}\n\nfunction errorResponse(error: unknown): Response {\n const actionError = toActionError(error);\n return Response.json(actionError.toBody(), {\n status: STATUS_BY_CODE[actionError.code],\n });\n}\n\nconst PLUGIN_NAME = /^[a-z][a-z0-9-]*$/;\nconst RESERVED_NAMES: ReadonlySet<string> = new Set([\n \"actions\",\n \"manifest\",\n \"mcp\",\n \"sync\",\n \"ui\",\n]);\n\nfunction checkPlugins(\n plugins: readonly ServerPlugin[],\n database: DataProvider | undefined,\n): void {\n const names = new Set<string>();\n for (const plugin of plugins) {\n if (!PLUGIN_NAME.test(plugin.name) || RESERVED_NAMES.has(plugin.name)) {\n throw new Error(`\"${plugin.name}\" cannot name a plugin.`);\n }\n if (names.has(plugin.name))\n throw new Error(`Two plugins are named \"${plugin.name}\".`);\n names.add(plugin.name);\n checkMigrations(plugin);\n if (plugin.migrations?.length && !database) {\n throw new Error(`The \"${plugin.name}\" plugin needs a database.`);\n }\n }\n}\n\ninterface MountedRoute {\n readonly plugin: string;\n readonly route: AnyPluginRoute;\n readonly path: string;\n}\n\nconst isAbsolute = (route: AnyPluginRoute) =>\n route.absolute === true || route.path.startsWith(\"/.well-known/\");\n\nfunction mountRoutes(\n runtimes: readonly { readonly plugin: ServerPlugin; readonly runtime: PluginRuntime }[],\n basePath: string,\n): MountedRoute[] {\n const mounted: MountedRoute[] = [];\n const owners = new Map<string, string>();\n for (const { plugin, runtime } of runtimes) {\n for (const route of runtime.routes ?? []) {\n if (!isAbsolute(route)) {\n mounted.push({\n plugin: plugin.name,\n route,\n path: `${basePath}/${plugin.name}${route.path}`,\n });\n continue;\n }\n const { method, path } = route;\n if (route.absolute && /[:*]/.test(path)) {\n throw new Error(\n `The \"${plugin.name}\" plugin's absolute route ${method} ${path} must be a static path.`,\n );\n }\n if (path === basePath || path.startsWith(`${basePath}/`)) {\n throw new Error(\n `The \"${plugin.name}\" plugin's absolute route ${method} ${path} is under ${basePath}, which the framework serves.`,\n );\n }\n const key = `${method} ${path}`;\n const owner = owners.get(key);\n if (owner !== undefined) {\n throw new Error(\n owner === plugin.name\n ? `The \"${owner}\" plugin serves ${key} twice.`\n : `The \"${owner}\" and \"${plugin.name}\" plugins both serve ${key}.`,\n );\n }\n owners.set(key, plugin.name);\n mounted.push({ plugin: plugin.name, route, path });\n }\n }\n return mounted;\n}\n\nfunction refuseShadowedRoutes(\n manifest: UiManifestInput | undefined,\n routes: readonly MountedRoute[],\n): void {\n if (!manifest) return;\n const pages = manifest.routes.map((page) => ({\n page,\n pattern: pagePattern(page.path),\n }));\n for (const { plugin, route } of routes) {\n if (!route.absolute || route.method !== \"GET\") continue;\n const shadow = pages.find(({ pattern }) => pattern.test(route.path));\n if (shadow) {\n throw new Error(\n `The \"${plugin}\" plugin's absolute route GET ${route.path} is also matched by the page route ${shadow.page.path}, so a browser opening it would get the page. Move one of them.`,\n );\n }\n }\n}\n\nfunction auditAll(\n runtimes: readonly PluginRuntime[],\n): ((record: ActionAudit) => void) | undefined {\n const hooks = runtimes.filter((runtime) => runtime.audit);\n if (hooks.length === 0) return undefined;\n return (record) => {\n for (const runtime of hooks) runtime.audit?.(record);\n };\n}\n\ninterface Installed {\n readonly plugin: ServerPlugin;\n readonly runtime: PluginRuntime;\n}\n\nasync function allowedBy({ runtime }: Installed, caller: PluginCaller): Promise<boolean> {\n return !runtime.allows || (await runtime.allows(caller));\n}\n\nfunction admitterOf(installed: Installed) {\n return async (caller: PluginCaller): Promise<void> => {\n if (await allowedBy(installed, caller)) return;\n throw new ActionError(\n \"forbidden\",\n `This account cannot use ${installed.plugin.name}.`,\n );\n };\n}\n\n/** Joins a connection to `channel` only once the plugin admits its holder. */\nfunction gatedChannel(installed: Installed, channel: ServerChannel): ServerChannel {\n if (!installed.runtime.allows) return channel;\n return {\n event: channel.event,\n connect(connection) {\n let detach: (() => void) | undefined;\n let left = false;\n allowedBy(installed, {\n principal: connection.principal ?? ANONYMOUS,\n scope: connection.scope,\n }).then(\n (allowed) => {\n if (allowed && !left && !connection.closed?.aborted) {\n detach = channel.connect(connection);\n }\n },\n (error: unknown) => {\n console.error(`[parlor] ${installed.plugin.name}: access check failed:`, error);\n },\n );\n return () => {\n left = true;\n detach?.();\n };\n },\n };\n}\n\nfunction guard(callers: CallerResolver, surface: Surface) {\n return async (request: Request): Promise<Caller> =>\n requireSurface(await callers(request), surface, callers.enforcing);\n}\n\nfunction refuseUnless(callers: CallerResolver, surface: Surface) {\n const check = guard(callers, surface);\n return async (event: H3Event): Promise<Response | undefined> => {\n try {\n await check(event.req);\n return undefined;\n } catch (error) {\n return errorResponse(error);\n }\n };\n}\n\nexport function createServer<T extends ActionMap>(\n options: ServerOptions<T>,\n): FrameworkServer {\n const {\n actions,\n scope = defaultScope,\n plugins = [],\n basePath = DEFAULT_BASE_PATH,\n cors = {},\n database,\n mcp = {},\n sync = {},\n agentUi: agentUiOptions = {},\n } = options;\n const auth = options.auth ?? (process.env.PARLOR_DEV === \"1\" ? devAuth() : undefined);\n const app = new H3();\n const appName = process.env.PARLOR_APP_NAME || undefined;\n const syncOptions = sync === false ? undefined : sync;\n const syncEnabled = syncOptions !== undefined && database !== undefined;\n const installed = [...(auth ? [auth] : []), ...plugins];\n checkPlugins(installed, database);\n let prepared: Promise<void> | undefined;\n const ready = () =>\n (prepared ??= (async () => {\n if (database) {\n await database.prepare?.();\n if (syncEnabled) await ensureSyncTables(database.read() as SyncDatabase);\n await applyMigrations(database, installed);\n }\n for (const { runtime } of runtimes) runtime.start?.();\n })());\n const callers = createCallerResolver(auth, scope, ready);\n const host: PluginHost = {\n basePath,\n database,\n ...(auth ? { auth } : {}),\n authMisconfigured: \"auth\" in options && auth === undefined,\n callerOf: callers,\n allows: async (name, caller) => {\n const entry = runtimes.find(({ plugin }) => plugin.name === name);\n return entry === undefined || (await allowedBy(entry, caller));\n },\n ready,\n announce: async (target, tags, within) => {\n if (!syncEnabled || !database || tags.length === 0) return;\n if (within !== undefined) {\n await recordSyncEvent(within as SyncDatabase, { scope: target, tags });\n return;\n }\n await ready();\n await database.transaction((tx) =>\n recordSyncEvent(tx as SyncDatabase, { scope: target, tags }),\n );\n },\n };\n const runtimes: Installed[] = installed.map((plugin) => ({\n plugin,\n runtime: plugin.setup(host),\n }));\n const routes = mountRoutes(runtimes, basePath);\n const audit = auditAll(runtimes.map(({ runtime }) => runtime));\n const agentUi =\n agentUiOptions === false\n ? undefined\n : createAgentUi({\n ...agentUiOptions,\n audience: async (request) => (await callers(request)).audience,\n });\n const runnerFor = (\n registry: ActionRegistry,\n admit?: (caller: Caller) => Promise<void>,\n ): ActionRunner =>\n createActionRunner({\n actions: registry,\n scope,\n callers,\n database,\n sync: syncEnabled,\n onClient: agentUi?.touch,\n confirm: agentUi?.confirm,\n audit,\n admit,\n ready,\n });\n const runner = runnerFor(actions);\n const hub = database ? new SyncHub(database) : undefined;\n const inflight = new Set<Promise<unknown>>();\n let closing: Promise<void> | undefined;\n\n if (cors !== false) app.use(corsMiddleware(cors));\n\n app.get(`${basePath}/manifest`, async (event): Promise<ManifestReply> => {\n let caller: Caller;\n try {\n caller = await callers(event.req);\n } catch (error) {\n return errorResponse(error);\n }\n const summary: ManifestSummary = {\n protocol: PROTOCOL_VERSION,\n ...(appName ? { app: { name: appName } } : {}),\n };\n if (!admits(\"manifest\", caller, callers.enforcing)) return summary;\n const ui = agentUi?.manifest();\n return { ...summary, actions: actions.describe(), ...(ui ? { ui } : {}) };\n });\n\n app.post(`${basePath}/actions/:name`, async (event) => {\n const name = event.context.params?.name ?? \"\";\n try {\n const input = await readBody(event).catch(() => {\n throw new ActionError(\"invalid_input\", \"Request body must be JSON\");\n });\n const result = await runner.run(name, input, event.req, sourceOf(event.req), {\n surface: \"actions\",\n cursor: true,\n });\n return { data: result.data, tags: result.reads, cursor: result.cursor };\n } catch (error) {\n return errorBody(event, error);\n }\n });\n\n const handleRoute = async (\n route: AnyPluginRoute,\n request: Request,\n admit: (caller: PluginCaller) => Promise<void>,\n ) => {\n if (route.access === \"public\") return route.handle(request);\n const caller = requireAccess(await callers(request), route.access, callers.enforcing);\n await admit(caller);\n return route.handle(request, caller);\n };\n\n const admitters = new Map(\n runtimes.map((entry) => [entry.plugin.name, admitterOf(entry)]),\n );\n for (const entry of runtimes) {\n const { plugin, runtime } = entry;\n if (runtime.actions) {\n const admit = admitters.get(plugin.name)!;\n const pluginRunner = runnerFor(runtime.actions, runtime.allows ? admit : undefined);\n app.post(`${basePath}/${plugin.name}/actions/:name`, async (event) => {\n const name = event.context.params?.name ?? \"\";\n try {\n const input = await readBody(event).catch(() => {\n throw new ActionError(\"invalid_input\", \"Request body must be JSON\");\n });\n const result = await pluginRunner.run(\n name,\n input,\n event.req,\n sourceOf(event.req),\n { surface: \"pluginActions\", cursor: true },\n );\n return { data: result.data, tags: result.reads, cursor: result.cursor };\n } catch (error) {\n return errorBody(event, error);\n }\n });\n }\n }\n for (const { plugin, route, path } of routes) {\n const admit = admitters.get(plugin)!;\n app.on(route.method, path, async (event) => {\n try {\n await ready();\n return await handleRoute(route, event.req, admit);\n } catch (error) {\n return errorResponse(error);\n }\n });\n }\n\n if (mcp !== false) {\n const mcpApp = appName\n ? {\n name: appName,\n ...(process.env.PARLOR_APP_DESCRIPTION\n ? { description: process.env.PARLOR_APP_DESCRIPTION }\n : {}),\n }\n : undefined;\n const handler = createMcpHandler({\n actions,\n runner,\n agentUi,\n callers,\n app: mcpApp,\n ...mcp,\n });\n const guardMcp = guard(callers, \"mcp\");\n app.all(`${basePath}/mcp`, async (event) => {\n try {\n await guardMcp(event.req);\n } catch (error) {\n const refusal = toActionError(error);\n const challenged =\n refusal.code === \"unauthenticated\" ||\n (await callers(event.req).then(\n ({ principal }) => principal.kind === \"host\",\n () => false,\n ));\n return challenged && auth ? auth.challenge(event.req) : errorResponse(refusal);\n }\n return handler.fetch(event.req);\n });\n }\n\n if (syncEnabled && database && hub) {\n app.use(`${basePath}/sync/**`, refuseUnless(callers, \"sync\"));\n app.use(`${basePath}/sync/**`, async () => {\n await ready();\n });\n registerSyncRoutes(app, {\n basePath,\n data: database,\n hub,\n scope: async (request) => (await callers(request)).scope,\n audience: async (request) => (await callers(request)).audience,\n authority: async (request) => {\n const caller = await callers(request);\n const { principal } = caller;\n return {\n principal,\n channels: admits(\"channels\", caller, callers.enforcing),\n ...(auth && principal.kind !== \"anonymous\"\n ? { revoked: auth.revoked(principal) }\n : {}),\n };\n },\n transport: syncOptions?.transport,\n pollIntervalMs: syncOptions?.pollIntervalMs,\n channels: [\n ...(agentUi ? [agentUi.channel] : []),\n ...runtimes.flatMap((entry): ServerChannel[] =>\n entry.runtime.channel ? [gatedChannel(entry, entry.runtime.channel)] : [],\n ),\n ],\n clientId: clientOf,\n });\n }\n\n if (agentUi) {\n app.use(`${basePath}/ui`, refuseUnless(callers, \"ui\"));\n registerAgentUiRoutes(app, {\n basePath,\n agentUi,\n audience: async (request) => (await callers(request)).audience,\n clientId: clientOf,\n });\n }\n\n app.all(\"/**\", (event) => {\n const response = errorResponse(\n new ActionError(\n \"not_found\",\n `No route for ${event.req.method} ${event.url.pathname}`,\n ),\n );\n response.headers.set(UNROUTED_HEADER, \"1\");\n return response;\n });\n\n return {\n installUiManifest: (source) => {\n refuseShadowedRoutes(source(), routes);\n agentUi?.install(source);\n },\n fetch: (request) => {\n const response = Promise.resolve(app.fetch(request));\n const settled = () => void inflight.delete(response);\n inflight.add(response);\n response.then(settled, settled);\n return response;\n },\n close: () =>\n (closing ??= (async () => {\n agentUi?.close();\n await Promise.allSettled(runtimes.map(({ runtime }) => runtime.close?.()));\n await Promise.all([hub?.stop(), Promise.allSettled([...inflight])]);\n await database?.close?.();\n })()),\n };\n}\n"]}
1
+ {"version":3,"file":"create-server.js","sourceRoot":"","sources":["../src/create-server.ts"],"names":[],"mappings":"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","sourcesContent":["import { pagePattern, UNROUTED_HEADER } from \"@parlor/agent-ui\";\nimport {\n type AgentUiOptions,\n createAgentUi,\n registerAgentUiRoutes,\n type UiManifestInput,\n type UiManifestSource,\n} from \"@parlor/agent-ui/server\";\nimport {\n ActionError,\n type ActionErrorCode,\n type ActionMap,\n ANONYMOUS,\n type DataProvider,\n decodeReadRequests,\n REFRESH_HEADER,\n} from \"@parlor/core\";\nimport type { ActionRegistry } from \"@parlor/core/registry\";\nimport type { ServerChannel } from \"@parlor/sync\";\nimport {\n ensureSyncTables,\n recordSyncEvent,\n registerSyncRoutes,\n type SyncDatabase,\n SyncHub,\n type SyncTransport,\n} from \"@parlor/sync/server\";\nimport { H3, type H3Event, readBody } from \"h3\";\n\nimport { admits, requireAccess, requireSurface, type Surface } from \"./access.js\";\nimport { type ActionRunner, createActionRunner } from \"./actions.js\";\nimport { AuthFailure, type AuthProvider } from \"./auth.js\";\nimport {\n type Caller,\n type CallerResolver,\n clientOf,\n createCallerResolver,\n sourceOf,\n} from \"./caller.js\";\nimport { type CorsConfig, corsMiddleware } from \"./cors.js\";\nimport { devAuth } from \"./dev-auth.js\";\nimport { createMcpHandler } from \"./mcp.js\";\nimport { applyMigrations, checkMigrations } from \"./migrations.js\";\nimport type {\n ActionAudit,\n AnyPluginRoute,\n PluginCaller,\n PluginHost,\n PluginRuntime,\n ServerPlugin,\n} from \"./plugin.js\";\nimport { DEFAULT_BASE_PATH, type Manifest, PROTOCOL_VERSION } from \"./protocol.js\";\nimport { refreshReads } from \"./refresh.js\";\nimport { defaultScope, type ScopeResolver } from \"./scope.js\";\n\nexport interface SyncOptions {\n readonly transport?: SyncTransport | undefined;\n readonly pollIntervalMs?: number | undefined;\n}\n\nexport interface ServerOptions<T extends ActionMap> {\n readonly actions: ActionRegistry<T>;\n readonly scope?: ScopeResolver | undefined;\n /**\n * Without it every caller is anonymous, the action source is the `x-parlor-source`\n * header, and confirmations are a UX guard.\n */\n readonly auth?: AuthProvider | undefined;\n /** Framework features with their own tables and routes, installed after `auth`. */\n readonly plugins?: readonly ServerPlugin[] | undefined;\n readonly basePath?: string | undefined;\n readonly cors?: CorsConfig | false | undefined;\n readonly database?: DataProvider | undefined;\n readonly mcp?:\n | { readonly name?: string | undefined; readonly version?: string | undefined }\n | false\n | undefined;\n readonly sync?: SyncOptions | false | undefined;\n readonly agentUi?: AgentUiOptions | false | undefined;\n}\n\ntype ManifestSummary = Pick<Manifest, \"protocol\" | \"app\">;\ntype ManifestReply = Manifest | ManifestSummary | Response;\n\nexport interface FrameworkServer {\n /**\n * Hands the server the app's page routes, called by the host before the first request.\n * Throws when a page route would take a document request meant for an absolute route.\n */\n readonly installUiManifest?: ((source: UiManifestSource) => void) | undefined;\n readonly fetch: (request: Request) => Promise<Response>;\n readonly close: () => Promise<void>;\n}\n\nconst STATUS_BY_CODE = {\n not_found: 404,\n invalid_input: 400,\n declined: 403,\n confirmation_timeout: 504,\n confirmation_unavailable: 503,\n unauthenticated: 401,\n forbidden: 403,\n internal: 500,\n} as const satisfies Record<ActionErrorCode, number>;\n\nconst isAbort = (error: unknown) => error instanceof Error && error.name === \"AbortError\";\n\nfunction toActionError(error: unknown): ActionError {\n if (error instanceof ActionError) return error;\n if (error instanceof AuthFailure)\n return new ActionError(\"unauthenticated\", error.message);\n if (!isAbort(error)) console.error(\"[parlor] action failed:\", error);\n return new ActionError(\"internal\", \"Internal error\", { cause: error });\n}\n\nfunction errorBody(event: H3Event, error: unknown) {\n const actionError = toActionError(error);\n event.res.status = STATUS_BY_CODE[actionError.code];\n return actionError.toBody();\n}\n\nfunction errorResponse(error: unknown): Response {\n const actionError = toActionError(error);\n return Response.json(actionError.toBody(), {\n status: STATUS_BY_CODE[actionError.code],\n });\n}\n\nconst PLUGIN_NAME = /^[a-z][a-z0-9-]*$/;\nconst RESERVED_NAMES: ReadonlySet<string> = new Set([\n \"actions\",\n \"manifest\",\n \"mcp\",\n \"sync\",\n \"ui\",\n]);\n\nfunction checkPlugins(\n plugins: readonly ServerPlugin[],\n database: DataProvider | undefined,\n): void {\n const names = new Set<string>();\n for (const plugin of plugins) {\n if (!PLUGIN_NAME.test(plugin.name) || RESERVED_NAMES.has(plugin.name)) {\n throw new Error(`\"${plugin.name}\" cannot name a plugin.`);\n }\n if (names.has(plugin.name))\n throw new Error(`Two plugins are named \"${plugin.name}\".`);\n names.add(plugin.name);\n checkMigrations(plugin);\n if (plugin.migrations?.length && !database) {\n throw new Error(`The \"${plugin.name}\" plugin needs a database.`);\n }\n }\n}\n\ninterface MountedRoute {\n readonly plugin: string;\n readonly route: AnyPluginRoute;\n readonly path: string;\n}\n\nconst isAbsolute = (route: AnyPluginRoute) =>\n route.absolute === true || route.path.startsWith(\"/.well-known/\");\n\nfunction mountRoutes(\n runtimes: readonly { readonly plugin: ServerPlugin; readonly runtime: PluginRuntime }[],\n basePath: string,\n): MountedRoute[] {\n const mounted: MountedRoute[] = [];\n const owners = new Map<string, string>();\n for (const { plugin, runtime } of runtimes) {\n for (const route of runtime.routes ?? []) {\n if (!isAbsolute(route)) {\n mounted.push({\n plugin: plugin.name,\n route,\n path: `${basePath}/${plugin.name}${route.path}`,\n });\n continue;\n }\n const { method, path } = route;\n if (route.absolute && /[:*]/.test(path)) {\n throw new Error(\n `The \"${plugin.name}\" plugin's absolute route ${method} ${path} must be a static path.`,\n );\n }\n if (path === basePath || path.startsWith(`${basePath}/`)) {\n throw new Error(\n `The \"${plugin.name}\" plugin's absolute route ${method} ${path} is under ${basePath}, which the framework serves.`,\n );\n }\n const key = `${method} ${path}`;\n const owner = owners.get(key);\n if (owner !== undefined) {\n throw new Error(\n owner === plugin.name\n ? `The \"${owner}\" plugin serves ${key} twice.`\n : `The \"${owner}\" and \"${plugin.name}\" plugins both serve ${key}.`,\n );\n }\n owners.set(key, plugin.name);\n mounted.push({ plugin: plugin.name, route, path });\n }\n }\n return mounted;\n}\n\nfunction refuseShadowedRoutes(\n manifest: UiManifestInput | undefined,\n routes: readonly MountedRoute[],\n): void {\n if (!manifest) return;\n const pages = manifest.routes.map((page) => ({\n page,\n pattern: pagePattern(page.path),\n }));\n for (const { plugin, route } of routes) {\n if (!route.absolute || route.method !== \"GET\") continue;\n const shadow = pages.find(({ pattern }) => pattern.test(route.path));\n if (shadow) {\n throw new Error(\n `The \"${plugin}\" plugin's absolute route GET ${route.path} is also matched by the page route ${shadow.page.path}, so a browser opening it would get the page. Move one of them.`,\n );\n }\n }\n}\n\nfunction auditAll(\n runtimes: readonly PluginRuntime[],\n): ((record: ActionAudit) => void) | undefined {\n const hooks = runtimes.filter((runtime) => runtime.audit);\n if (hooks.length === 0) return undefined;\n return (record) => {\n for (const runtime of hooks) runtime.audit?.(record);\n };\n}\n\ninterface Installed {\n readonly plugin: ServerPlugin;\n readonly runtime: PluginRuntime;\n}\n\nasync function allowedBy({ runtime }: Installed, caller: PluginCaller): Promise<boolean> {\n return !runtime.allows || (await runtime.allows(caller));\n}\n\nfunction admitterOf(installed: Installed) {\n return async (caller: PluginCaller): Promise<void> => {\n if (await allowedBy(installed, caller)) return;\n throw new ActionError(\n \"forbidden\",\n `This account cannot use ${installed.plugin.name}.`,\n );\n };\n}\n\n/** Joins a connection to `channel` only once the plugin admits its holder. */\nfunction gatedChannel(installed: Installed, channel: ServerChannel): ServerChannel {\n if (!installed.runtime.allows) return channel;\n return {\n event: channel.event,\n hosts: channel.hosts,\n connect(connection) {\n let detach: (() => void) | undefined;\n let left = false;\n allowedBy(installed, {\n principal: connection.principal ?? ANONYMOUS,\n scope: connection.scope,\n }).then(\n (allowed) => {\n if (allowed && !left && !connection.closed?.aborted) {\n detach = channel.connect(connection);\n }\n },\n (error: unknown) => {\n console.error(`[parlor] ${installed.plugin.name}: access check failed:`, error);\n },\n );\n return () => {\n left = true;\n detach?.();\n };\n },\n };\n}\n\nfunction guard(callers: CallerResolver, surface: Surface) {\n return async (request: Request): Promise<Caller> =>\n requireSurface(await callers(request), surface, callers.enforcing);\n}\n\nfunction refuseUnless(callers: CallerResolver, surface: Surface) {\n const check = guard(callers, surface);\n return async (event: H3Event): Promise<Response | undefined> => {\n try {\n await check(event.req);\n return undefined;\n } catch (error) {\n return errorResponse(error);\n }\n };\n}\n\nexport function createServer<T extends ActionMap>(\n options: ServerOptions<T>,\n): FrameworkServer {\n const {\n actions,\n scope = defaultScope,\n plugins = [],\n basePath = DEFAULT_BASE_PATH,\n cors = {},\n database,\n mcp = {},\n sync = {},\n agentUi: agentUiOptions = {},\n } = options;\n const auth = options.auth ?? (process.env.PARLOR_DEV === \"1\" ? devAuth() : undefined);\n const app = new H3();\n const appName = process.env.PARLOR_APP_NAME || undefined;\n const syncOptions = sync === false ? undefined : sync;\n const syncEnabled = syncOptions !== undefined && database !== undefined;\n const installed = [...(auth ? [auth] : []), ...plugins];\n checkPlugins(installed, database);\n let prepared: Promise<void> | undefined;\n const ready = () =>\n (prepared ??= (async () => {\n if (database) {\n await database.prepare?.();\n if (syncEnabled) await ensureSyncTables(database.read() as SyncDatabase);\n await applyMigrations(database, installed);\n }\n for (const { runtime } of runtimes) runtime.start?.();\n })());\n const callers = createCallerResolver(auth, scope, ready);\n const host: PluginHost = {\n basePath,\n database,\n ...(auth ? { auth } : {}),\n authMisconfigured: \"auth\" in options && auth === undefined,\n callerOf: callers,\n allows: async (name, caller) => {\n const entry = runtimes.find(({ plugin }) => plugin.name === name);\n return entry === undefined || (await allowedBy(entry, caller));\n },\n ready,\n announce: async (target, tags, within) => {\n if (!syncEnabled || !database || tags.length === 0) return;\n if (within !== undefined) {\n await recordSyncEvent(within as SyncDatabase, { scope: target, tags });\n return;\n }\n await ready();\n await database.transaction((tx) =>\n recordSyncEvent(tx as SyncDatabase, { scope: target, tags }),\n );\n },\n };\n const runtimes: Installed[] = installed.map((plugin) => ({\n plugin,\n runtime: plugin.setup(host),\n }));\n const routes = mountRoutes(runtimes, basePath);\n const audit = auditAll(runtimes.map(({ runtime }) => runtime));\n const agentUi =\n agentUiOptions === false\n ? undefined\n : createAgentUi({\n ...agentUiOptions,\n audience: async (request) => (await callers(request)).audience,\n });\n const runnerFor = (\n registry: ActionRegistry,\n admit?: (caller: Caller) => Promise<void>,\n ): ActionRunner =>\n createActionRunner({\n actions: registry,\n scope,\n callers,\n database,\n sync: syncEnabled,\n onClient: agentUi?.touch,\n confirm: agentUi?.confirm,\n audit,\n admit,\n ready,\n });\n const runner = runnerFor(actions);\n const hub = database ? new SyncHub(database) : undefined;\n const inflight = new Set<Promise<unknown>>();\n let closing: Promise<void> | undefined;\n\n if (cors !== false) app.use(corsMiddleware(cors));\n\n app.get(`${basePath}/manifest`, async (event): Promise<ManifestReply> => {\n let caller: Caller;\n try {\n caller = await callers(event.req);\n } catch (error) {\n return errorResponse(error);\n }\n const summary: ManifestSummary = {\n protocol: PROTOCOL_VERSION,\n ...(appName ? { app: { name: appName } } : {}),\n };\n if (!admits(\"manifest\", caller, callers.enforcing)) return summary;\n const ui = agentUi?.manifest();\n return { ...summary, actions: actions.describe(), ...(ui ? { ui } : {}) };\n });\n\n app.post(`${basePath}/actions/:name`, async (event) => {\n const name = event.context.params?.name ?? \"\";\n try {\n const input = await readBody(event).catch(() => {\n throw new ActionError(\"invalid_input\", \"Request body must be JSON\");\n });\n const source = sourceOf(event.req);\n const run = (action: string, actionInput: unknown) =>\n runner.run(action, actionInput, event.req, source, {\n surface: \"actions\",\n cursor: true,\n });\n const result = await run(name, input);\n const answer = { data: result.data, tags: result.reads, cursor: result.cursor };\n const reads = decodeReadRequests(event.req.headers.get(REFRESH_HEADER));\n if (!reads) return answer;\n const refreshed = await refreshReads(\n actions,\n reads,\n result.writes,\n async (action, actionInput) => {\n const read = await run(action, actionInput);\n return { data: read.data, tags: read.reads, cursor: read.cursor };\n },\n (error) => toActionError(error).toBody(),\n );\n return { ...answer, writes: result.writes, refreshed };\n } catch (error) {\n return errorBody(event, error);\n }\n });\n\n const handleRoute = async (\n route: AnyPluginRoute,\n request: Request,\n admit: (caller: PluginCaller) => Promise<void>,\n ) => {\n if (route.access === \"public\") return route.handle(request);\n const caller = requireAccess(await callers(request), route.access, callers.enforcing);\n await admit(caller);\n return route.handle(request, caller);\n };\n\n const admitters = new Map(\n runtimes.map((entry) => [entry.plugin.name, admitterOf(entry)]),\n );\n for (const entry of runtimes) {\n const { plugin, runtime } = entry;\n if (runtime.actions) {\n const admit = admitters.get(plugin.name)!;\n const pluginRunner = runnerFor(runtime.actions, runtime.allows ? admit : undefined);\n app.post(`${basePath}/${plugin.name}/actions/:name`, async (event) => {\n const name = event.context.params?.name ?? \"\";\n try {\n const input = await readBody(event).catch(() => {\n throw new ActionError(\"invalid_input\", \"Request body must be JSON\");\n });\n const result = await pluginRunner.run(\n name,\n input,\n event.req,\n sourceOf(event.req),\n { surface: \"pluginActions\", cursor: true },\n );\n return { data: result.data, tags: result.reads, cursor: result.cursor };\n } catch (error) {\n return errorBody(event, error);\n }\n });\n }\n }\n for (const { plugin, route, path } of routes) {\n const admit = admitters.get(plugin)!;\n app.on(route.method, path, async (event) => {\n try {\n await ready();\n return await handleRoute(route, event.req, admit);\n } catch (error) {\n return errorResponse(error);\n }\n });\n }\n\n if (mcp !== false) {\n const mcpApp = appName\n ? {\n name: appName,\n ...(process.env.PARLOR_APP_DESCRIPTION\n ? { description: process.env.PARLOR_APP_DESCRIPTION }\n : {}),\n }\n : undefined;\n const handler = createMcpHandler({\n actions,\n runner,\n agentUi,\n callers,\n app: mcpApp,\n ...mcp,\n });\n const guardMcp = guard(callers, \"mcp\");\n app.all(`${basePath}/mcp`, async (event) => {\n try {\n await guardMcp(event.req);\n } catch (error) {\n const refusal = toActionError(error);\n const challenged =\n refusal.code === \"unauthenticated\" ||\n (await callers(event.req).then(\n ({ principal }) => principal.kind === \"host\",\n () => false,\n ));\n return challenged && auth ? auth.challenge(event.req) : errorResponse(refusal);\n }\n return handler.fetch(event.req);\n });\n }\n\n if (syncEnabled && database && hub) {\n app.use(`${basePath}/sync/**`, refuseUnless(callers, \"sync\"));\n app.use(`${basePath}/sync/**`, async () => {\n await ready();\n });\n registerSyncRoutes(app, {\n basePath,\n data: database,\n hub,\n scope: async (request) => (await callers(request)).scope,\n audience: async (request) => (await callers(request)).audience,\n authority: async (request) => {\n const caller = await callers(request);\n const { principal } = caller;\n return {\n principal,\n channels: admits(\"channels\", caller, callers.enforcing)\n ? true\n : (channel: ServerChannel) =>\n principal.kind === \"host\" && channel.hosts === true,\n ...(auth && principal.kind !== \"anonymous\"\n ? { revoked: auth.revoked(principal) }\n : {}),\n };\n },\n transport: syncOptions?.transport,\n pollIntervalMs: syncOptions?.pollIntervalMs,\n channels: [\n ...(agentUi ? [agentUi.channel] : []),\n ...runtimes.flatMap((entry): ServerChannel[] =>\n entry.runtime.channel ? [gatedChannel(entry, entry.runtime.channel)] : [],\n ),\n ],\n clientId: clientOf,\n });\n }\n\n if (agentUi) {\n app.use(`${basePath}/ui`, refuseUnless(callers, \"ui\"));\n registerAgentUiRoutes(app, {\n basePath,\n agentUi,\n audience: async (request) => (await callers(request)).audience,\n clientId: clientOf,\n });\n }\n\n app.all(\"/**\", (event) => {\n const response = errorResponse(\n new ActionError(\n \"not_found\",\n `No route for ${event.req.method} ${event.url.pathname}`,\n ),\n );\n response.headers.set(UNROUTED_HEADER, \"1\");\n return response;\n });\n\n return {\n installUiManifest: (source) => {\n refuseShadowedRoutes(source(), routes);\n agentUi?.install(source);\n },\n fetch: (request) => {\n const response = Promise.resolve(app.fetch(request));\n const settled = () => void inflight.delete(response);\n inflight.add(response);\n response.then(settled, settled);\n return response;\n },\n close: () =>\n (closing ??= (async () => {\n agentUi?.close();\n await Promise.allSettled(runtimes.map(({ runtime }) => runtime.close?.()));\n await Promise.all([hub?.stop(), Promise.allSettled([...inflight])]);\n await database?.close?.();\n })()),\n };\n}\n"]}
@@ -0,0 +1,14 @@
1
+ import { type ActionErrorBody, type ReadRequest, type RefreshedRead, type Tag } from "@parlor/core";
2
+ import type { ActionRegistry } from "@parlor/core/registry";
3
+ export interface ReadRun {
4
+ readonly data: unknown;
5
+ readonly tags: readonly Tag[];
6
+ readonly cursor?: string | undefined;
7
+ }
8
+ /**
9
+ * The reads a page named on a write, each run again after it when the write changed what it
10
+ * shows, else null. Each runs as its own call, with the caller's own access; one that fails
11
+ * answers its error and leaves the others.
12
+ */
13
+ export declare function refreshReads(actions: ActionRegistry, requests: readonly ReadRequest[], writes: readonly Tag[], run: (name: string, input: unknown) => Promise<ReadRun>, errorBody: (error: unknown) => ActionErrorBody): Promise<RefreshedRead[]>;
14
+ //# sourceMappingURL=refresh.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../src/refresh.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,eAAe,EAEpB,KAAK,WAAW,EAChB,KAAK,aAAa,EAElB,KAAK,GAAG,EAET,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,EAAE,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC;AAiBD;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,SAAS,WAAW,EAAE,EAChC,MAAM,EAAE,SAAS,GAAG,EAAE,EACtB,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,EACvD,SAAS,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,eAAe,GAC7C,OAAO,CAAC,aAAa,EAAE,CAAC,CAY1B"}
@@ -0,0 +1,30 @@
1
+ import { isMutating, readTagsFor, tagsOverlap, } from "@parlor/core";
2
+ /** Whether a read shows anything `writes` changed, by the tables it declares for its input. */
3
+ function touched(actions, [name, input], writes) {
4
+ const action = actions.get(name);
5
+ if (!action || isMutating(action) || writes.length === 0)
6
+ return false;
7
+ const parsed = action.input.safeParse(input);
8
+ if (!parsed.success)
9
+ return false;
10
+ return readTagsFor(action, parsed.data).some((read) => writes.some((write) => tagsOverlap(read, write)));
11
+ }
12
+ /**
13
+ * The reads a page named on a write, each run again after it when the write changed what it
14
+ * shows, else null. Each runs as its own call, with the caller's own access; one that fails
15
+ * answers its error and leaves the others.
16
+ */
17
+ export function refreshReads(actions, requests, writes, run, errorBody) {
18
+ return Promise.all(requests.map(async (request) => {
19
+ if (!touched(actions, request, writes))
20
+ return null;
21
+ try {
22
+ const { data, tags, cursor } = await run(request[0], request[1]);
23
+ return cursor === undefined ? { data, tags } : { data, tags, cursor };
24
+ }
25
+ catch (error) {
26
+ return errorBody(error);
27
+ }
28
+ }));
29
+ }
30
+ //# sourceMappingURL=refresh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refresh.js","sourceRoot":"","sources":["../src/refresh.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,UAAU,EAGV,WAAW,EAEX,WAAW,GACZ,MAAM,cAAc,CAAC;AAStB,+FAA+F;AAC/F,SAAS,OAAO,CACd,OAAuB,EACvB,CAAC,IAAI,EAAE,KAAK,CAAc,EAC1B,MAAsB;IAEtB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,CAAC,MAAM,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACvE,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC7C,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAClC,OAAO,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CACpD,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CACjD,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAC1B,OAAuB,EACvB,QAAgC,EAChC,MAAsB,EACtB,GAAuD,EACvD,SAA8C;IAE9C,OAAO,OAAO,CAAC,GAAG,CAChB,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,EAA0B,EAAE;QACrD,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC;YAAE,OAAO,IAAI,CAAC;QACpD,IAAI,CAAC;YACH,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;YACjE,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QACxE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CAAC,CACH,CAAC;AACJ,CAAC","sourcesContent":["import {\n type ActionErrorBody,\n isMutating,\n type ReadRequest,\n type RefreshedRead,\n readTagsFor,\n type Tag,\n tagsOverlap,\n} from \"@parlor/core\";\nimport type { ActionRegistry } from \"@parlor/core/registry\";\n\nexport interface ReadRun {\n readonly data: unknown;\n readonly tags: readonly Tag[];\n readonly cursor?: string | undefined;\n}\n\n/** Whether a read shows anything `writes` changed, by the tables it declares for its input. */\nfunction touched(\n actions: ActionRegistry,\n [name, input]: ReadRequest,\n writes: readonly Tag[],\n) {\n const action = actions.get(name);\n if (!action || isMutating(action) || writes.length === 0) return false;\n const parsed = action.input.safeParse(input);\n if (!parsed.success) return false;\n return readTagsFor(action, parsed.data).some((read) =>\n writes.some((write) => tagsOverlap(read, write)),\n );\n}\n\n/**\n * The reads a page named on a write, each run again after it when the write changed what it\n * shows, else null. Each runs as its own call, with the caller's own access; one that fails\n * answers its error and leaves the others.\n */\nexport function refreshReads(\n actions: ActionRegistry,\n requests: readonly ReadRequest[],\n writes: readonly Tag[],\n run: (name: string, input: unknown) => Promise<ReadRun>,\n errorBody: (error: unknown) => ActionErrorBody,\n): Promise<RefreshedRead[]> {\n return Promise.all(\n requests.map(async (request): Promise<RefreshedRead> => {\n if (!touched(actions, request, writes)) return null;\n try {\n const { data, tags, cursor } = await run(request[0], request[1]);\n return cursor === undefined ? { data, tags } : { data, tags, cursor };\n } catch (error) {\n return errorBody(error);\n }\n }),\n );\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parlor/server",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "homepage": "https://cychien.github.io/parlor",
5
5
  "bugs": "https://github.com/cychien/parlor/issues",
6
6
  "license": "MIT",
@@ -24,9 +24,9 @@
24
24
  "drizzle-orm": "^0.45.4",
25
25
  "h3": "^2.0.1",
26
26
  "zod": "^4.6.5",
27
- "@parlor/agent-ui": "0.3.0",
28
- "@parlor/core": "0.3.0",
29
- "@parlor/sync": "0.3.0"
27
+ "@parlor/agent-ui": "0.3.1",
28
+ "@parlor/core": "0.3.1",
29
+ "@parlor/sync": "0.3.1"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@modelcontextprotocol/client": "^2.3.1",
@@ -34,7 +34,7 @@
34
34
  "srvx": "^1.0.5",
35
35
  "typescript": "^7.0.2",
36
36
  "vitest": "^5.0.3",
37
- "@parlor/data": "0.3.0"
37
+ "@parlor/data": "0.3.1"
38
38
  },
39
39
  "scripts": {
40
40
  "build": "tsc -p tsconfig.json",