@parlor/server 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +19 -2
- package/dist/access.d.ts +27 -0
- package/dist/access.d.ts.map +1 -0
- package/dist/access.js +41 -0
- package/dist/access.js.map +1 -0
- package/dist/actions.d.ts +43 -0
- package/dist/actions.d.ts.map +1 -0
- package/dist/actions.js +169 -0
- package/dist/actions.js.map +1 -0
- package/dist/auth.d.ts +97 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +11 -0
- package/dist/auth.js.map +1 -0
- package/dist/body.d.ts +7 -0
- package/dist/body.d.ts.map +1 -0
- package/dist/body.js +29 -0
- package/dist/body.js.map +1 -0
- package/dist/caller.d.ts +21 -0
- package/dist/caller.d.ts.map +1 -0
- package/dist/caller.js +46 -0
- package/dist/caller.js.map +1 -0
- package/dist/cors.d.ts +9 -0
- package/dist/cors.d.ts.map +1 -0
- package/dist/cors.js +25 -0
- package/dist/cors.js.map +1 -0
- package/dist/create-server.d.ts +43 -0
- package/dist/create-server.d.ts.map +1 -0
- package/dist/create-server.js +422 -0
- package/dist/create-server.js.map +1 -0
- package/dist/dev-auth.d.ts +17 -0
- package/dist/dev-auth.d.ts.map +1 -0
- package/dist/dev-auth.js +146 -0
- package/dist/dev-auth.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-calls.d.ts +7 -0
- package/dist/mcp-calls.d.ts.map +1 -0
- package/dist/mcp-calls.js +30 -0
- package/dist/mcp-calls.js.map +1 -0
- package/dist/mcp.d.ts +29 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +198 -0
- package/dist/mcp.js.map +1 -0
- package/dist/migrations.d.ts +10 -0
- package/dist/migrations.d.ts.map +1 -0
- package/dist/migrations.js +81 -0
- package/dist/migrations.js.map +1 -0
- package/dist/plugin.d.ts +117 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +5 -0
- package/dist/plugin.js.map +1 -0
- package/dist/protocol.d.ts +18 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +7 -0
- package/dist/protocol.js.map +1 -0
- package/dist/revocation-horizon.d.ts +6 -0
- package/dist/revocation-horizon.d.ts.map +1 -0
- package/dist/revocation-horizon.js +6 -0
- package/dist/revocation-horizon.js.map +1 -0
- package/dist/scope.d.ts +6 -0
- package/dist/scope.d.ts.map +1 -0
- package/dist/scope.js +4 -0
- package/dist/scope.js.map +1 -0
- package/package.json +41 -3
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { sql } from "drizzle-orm";
|
|
2
|
+
const MIGRATION_LOCK_KEY = 7_311_208;
|
|
3
|
+
export function checkMigrations(plugin) {
|
|
4
|
+
const seen = new Set();
|
|
5
|
+
for (const { id } of plugin.migrations ?? []) {
|
|
6
|
+
if (!id.startsWith(`${plugin.name}/`)) {
|
|
7
|
+
throw new Error(`Migration "${id}" must start with "${plugin.name}/".`);
|
|
8
|
+
}
|
|
9
|
+
if (seen.has(id))
|
|
10
|
+
throw new Error(`Migration "${id}" is listed twice.`);
|
|
11
|
+
seen.add(id);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
const DOLLAR_TAG = /^\$[A-Za-z_]*\$/;
|
|
15
|
+
/**
|
|
16
|
+
* PGlite refuses several commands in one prepared statement, so a migration is run one
|
|
17
|
+
* statement at a time. Quotes, comments and dollar-quoted bodies may hold semicolons.
|
|
18
|
+
*/
|
|
19
|
+
export function splitStatements(script) {
|
|
20
|
+
const statements = [];
|
|
21
|
+
let start = 0;
|
|
22
|
+
let at = 0;
|
|
23
|
+
const skipTo = (end) => {
|
|
24
|
+
const close = script.indexOf(end, at);
|
|
25
|
+
at = close === -1 ? script.length : close + end.length;
|
|
26
|
+
};
|
|
27
|
+
while (at < script.length) {
|
|
28
|
+
const char = script[at];
|
|
29
|
+
if (char === "'" || char === '"') {
|
|
30
|
+
at += 1;
|
|
31
|
+
skipTo(char);
|
|
32
|
+
}
|
|
33
|
+
else if (script.startsWith("--", at)) {
|
|
34
|
+
skipTo("\n");
|
|
35
|
+
}
|
|
36
|
+
else if (script.startsWith("/*", at)) {
|
|
37
|
+
skipTo("*/");
|
|
38
|
+
}
|
|
39
|
+
else if (char === "$" && DOLLAR_TAG.test(script.slice(at))) {
|
|
40
|
+
const tag = DOLLAR_TAG.exec(script.slice(at))[0];
|
|
41
|
+
at += tag.length;
|
|
42
|
+
skipTo(tag);
|
|
43
|
+
}
|
|
44
|
+
else if (char === ";") {
|
|
45
|
+
statements.push(script.slice(start, at));
|
|
46
|
+
at += 1;
|
|
47
|
+
start = at;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
at += 1;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
statements.push(script.slice(start));
|
|
54
|
+
return statements.map((statement) => statement.trim()).filter(Boolean);
|
|
55
|
+
}
|
|
56
|
+
export async function applyMigrations(database, plugins) {
|
|
57
|
+
const migrations = plugins.flatMap((plugin) => plugin.migrations ?? []);
|
|
58
|
+
if (migrations.length === 0)
|
|
59
|
+
return;
|
|
60
|
+
await database.transaction(async (handle) => {
|
|
61
|
+
const tx = handle;
|
|
62
|
+
await tx.execute(sql `select pg_advisory_xact_lock(${MIGRATION_LOCK_KEY})`);
|
|
63
|
+
await tx.execute(sql `
|
|
64
|
+
create table if not exists parlor_migrations (
|
|
65
|
+
id text primary key,
|
|
66
|
+
applied_at timestamptz not null default now()
|
|
67
|
+
)`);
|
|
68
|
+
const result = (await tx.execute(sql `select id from parlor_migrations`));
|
|
69
|
+
const rows = Array.isArray(result) ? result : (result.rows ?? []);
|
|
70
|
+
const applied = new Set(rows.map((row) => row.id));
|
|
71
|
+
for (const migration of migrations) {
|
|
72
|
+
if (applied.has(migration.id))
|
|
73
|
+
continue;
|
|
74
|
+
for (const statement of splitStatements(migration.sql)) {
|
|
75
|
+
await tx.execute(sql.raw(statement));
|
|
76
|
+
}
|
|
77
|
+
await tx.execute(sql `insert into parlor_migrations (id) values (${migration.id})`);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=migrations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrations.js","sourceRoot":"","sources":["../src/migrations.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DataProvider } from \"@parlor/core\";\nimport { sql } from \"drizzle-orm\";\nimport type { PgDatabase, PgQueryResultHKT } from \"drizzle-orm/pg-core\";\n\nimport type { ServerPlugin } from \"./plugin.js\";\n\ntype Database = PgDatabase<PgQueryResultHKT>;\n\nconst MIGRATION_LOCK_KEY = 7_311_208;\n\nexport function checkMigrations(plugin: ServerPlugin): void {\n const seen = new Set<string>();\n for (const { id } of plugin.migrations ?? []) {\n if (!id.startsWith(`${plugin.name}/`)) {\n throw new Error(`Migration \"${id}\" must start with \"${plugin.name}/\".`);\n }\n if (seen.has(id)) throw new Error(`Migration \"${id}\" is listed twice.`);\n seen.add(id);\n }\n}\n\nconst DOLLAR_TAG = /^\\$[A-Za-z_]*\\$/;\n\n/**\n * PGlite refuses several commands in one prepared statement, so a migration is run one\n * statement at a time. Quotes, comments and dollar-quoted bodies may hold semicolons.\n */\nexport function splitStatements(script: string): string[] {\n const statements: string[] = [];\n let start = 0;\n let at = 0;\n const skipTo = (end: string) => {\n const close = script.indexOf(end, at);\n at = close === -1 ? script.length : close + end.length;\n };\n while (at < script.length) {\n const char = script[at]!;\n if (char === \"'\" || char === '\"') {\n at += 1;\n skipTo(char);\n } else if (script.startsWith(\"--\", at)) {\n skipTo(\"\\n\");\n } else if (script.startsWith(\"/*\", at)) {\n skipTo(\"*/\");\n } else if (char === \"$\" && DOLLAR_TAG.test(script.slice(at))) {\n const tag = DOLLAR_TAG.exec(script.slice(at))![0];\n at += tag.length;\n skipTo(tag);\n } else if (char === \";\") {\n statements.push(script.slice(start, at));\n at += 1;\n start = at;\n } else {\n at += 1;\n }\n }\n statements.push(script.slice(start));\n return statements.map((statement) => statement.trim()).filter(Boolean);\n}\n\nexport async function applyMigrations(\n database: DataProvider,\n plugins: readonly ServerPlugin[],\n): Promise<void> {\n const migrations = plugins.flatMap((plugin) => plugin.migrations ?? []);\n if (migrations.length === 0) return;\n await database.transaction(async (handle) => {\n const tx = handle as Database;\n await tx.execute(sql`select pg_advisory_xact_lock(${MIGRATION_LOCK_KEY})`);\n await tx.execute(sql`\n create table if not exists parlor_migrations (\n id text primary key,\n applied_at timestamptz not null default now()\n )`);\n const result = (await tx.execute(sql`select id from parlor_migrations`)) as\n | { rows?: { id: string }[] }\n | { id: string }[];\n const rows = Array.isArray(result) ? result : (result.rows ?? []);\n const applied = new Set(rows.map((row) => row.id));\n for (const migration of migrations) {\n if (applied.has(migration.id)) continue;\n for (const statement of splitStatements(migration.sql)) {\n await tx.execute(sql.raw(statement));\n }\n await tx.execute(sql`insert into parlor_migrations (id) values (${migration.id})`);\n }\n });\n}\n"]}
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import type { ActionErrorCode, ActionSource, AuthenticatedPrincipal, DataProvider, Principal, Tag } from "@parlor/core";
|
|
2
|
+
import type { ActionRegistry } from "@parlor/core/registry";
|
|
3
|
+
import type { ServerChannel } from "@parlor/sync";
|
|
4
|
+
import type { CallerOf } from "./access.js";
|
|
5
|
+
import type { AuthProvider } from "./auth.js";
|
|
6
|
+
import type { Caller } from "./caller.js";
|
|
7
|
+
/**
|
|
8
|
+
* A framework feature the app installs with `createServer({ plugins })`. It owns the
|
|
9
|
+
* tables prefixed `parlor_<name>_`, every path under `/_parlor/<name>/`, and the paths its
|
|
10
|
+
* absolute routes declare.
|
|
11
|
+
*/
|
|
12
|
+
export interface ServerPlugin {
|
|
13
|
+
readonly name: string;
|
|
14
|
+
readonly migrations?: readonly Migration[] | undefined;
|
|
15
|
+
setup(host: PluginHost): PluginRuntime;
|
|
16
|
+
}
|
|
17
|
+
/** Applied once per database in list order. An applied id must never change. */
|
|
18
|
+
export interface Migration {
|
|
19
|
+
readonly id: `${string}/${number}_${string}`;
|
|
20
|
+
readonly sql: string;
|
|
21
|
+
}
|
|
22
|
+
export interface PluginRuntime {
|
|
23
|
+
/**
|
|
24
|
+
* Served at `POST /_parlor/<plugin>/actions/<action>` through the same runner as the app's
|
|
25
|
+
* actions, but never listed on MCP and never callable by an agent.
|
|
26
|
+
*/
|
|
27
|
+
readonly actions?: ActionRegistry | undefined;
|
|
28
|
+
readonly channel?: ServerChannel | undefined;
|
|
29
|
+
readonly routes?: readonly AnyPluginRoute[] | undefined;
|
|
30
|
+
/** Called once per action call on every surface after it settles, whatever the outcome. */
|
|
31
|
+
audit?(record: ActionAudit): void;
|
|
32
|
+
/**
|
|
33
|
+
* Starts the plugin's background work, such as timers. Called once, when the server is
|
|
34
|
+
* ready for its first request: some runtimes allow no timers while the app loads.
|
|
35
|
+
*/
|
|
36
|
+
start?(): void;
|
|
37
|
+
/**
|
|
38
|
+
* Who may use the plugin. Everyone else gets `forbidden` from its actions and signed-in
|
|
39
|
+
* routes and never joins its channel. Absent admits whoever those surfaces admit.
|
|
40
|
+
*/
|
|
41
|
+
allows?(caller: PluginCaller): boolean | Promise<boolean>;
|
|
42
|
+
/** Runs before `close()` awaits in-flight requests, so it must end what it holds open. */
|
|
43
|
+
close?(): void | Promise<void>;
|
|
44
|
+
}
|
|
45
|
+
/** Who is asking: enough to look the user up, with no request to read. */
|
|
46
|
+
export type PluginCaller = Pick<Caller, "principal" | "scope">;
|
|
47
|
+
export interface ActionAudit {
|
|
48
|
+
readonly at: number;
|
|
49
|
+
readonly action: string;
|
|
50
|
+
readonly principal: Principal;
|
|
51
|
+
readonly source: ActionSource;
|
|
52
|
+
readonly scope: string;
|
|
53
|
+
/** SHA-256 of the input as received; the input itself is not kept. */
|
|
54
|
+
readonly inputDigest: string;
|
|
55
|
+
/** `ran` once `run` started; `refused` when the call stopped before it. */
|
|
56
|
+
readonly stage: "refused" | "ran";
|
|
57
|
+
readonly outcome: "ok" | "cancelled" | ActionErrorCode;
|
|
58
|
+
readonly confirmation?: ConfirmationAnswer | undefined;
|
|
59
|
+
}
|
|
60
|
+
export type ConfirmationAnswer = "approved" | "declined" | "timeout" | "unavailable";
|
|
61
|
+
type SignedInKind = AuthenticatedPrincipal["kind"];
|
|
62
|
+
/**
|
|
63
|
+
* A plain route with no transaction or sync event. `access` decides who may call it and
|
|
64
|
+
* types the caller its handler receives. An anonymous caller is admitted only when `access`
|
|
65
|
+
* lists it and no enforcing auth provider is installed.
|
|
66
|
+
*/
|
|
67
|
+
export interface PluginRoute<K extends SignedInKind | "anonymous"> {
|
|
68
|
+
readonly method: "GET" | "POST";
|
|
69
|
+
readonly path: `/${string}`;
|
|
70
|
+
/**
|
|
71
|
+
* Serves `path` as is from the origin root instead of under `/_parlor/<plugin>/`, for URLs
|
|
72
|
+
* fixed outside the app, such as a payment provider's webhook. The path must be static.
|
|
73
|
+
*/
|
|
74
|
+
readonly absolute?: boolean | undefined;
|
|
75
|
+
readonly access: readonly K[];
|
|
76
|
+
handle(request: Request, caller: CallerOf<K>): Promise<Response>;
|
|
77
|
+
}
|
|
78
|
+
/** Callable by anyone, signed in or not: sign-in pages, OAuth endpoints. */
|
|
79
|
+
export interface PublicPluginRoute {
|
|
80
|
+
readonly method: "GET" | "POST";
|
|
81
|
+
/** Absolute when it starts with `/.well-known/`. */
|
|
82
|
+
readonly path: `/${string}`;
|
|
83
|
+
/** See `PluginRoute.absolute`. */
|
|
84
|
+
readonly absolute?: boolean | undefined;
|
|
85
|
+
readonly access: "public";
|
|
86
|
+
handle(request: Request): Promise<Response>;
|
|
87
|
+
}
|
|
88
|
+
export type AnyPluginRoute = PluginRoute<SignedInKind | "anonymous"> | PublicPluginRoute;
|
|
89
|
+
/** Infers `K` from `access`, so the handler's caller type follows the list. */
|
|
90
|
+
export declare function pluginRoute<const K extends SignedInKind | "anonymous">(route: PluginRoute<K>): PluginRoute<K>;
|
|
91
|
+
export interface PluginHost {
|
|
92
|
+
readonly basePath: string;
|
|
93
|
+
readonly database: DataProvider | undefined;
|
|
94
|
+
/** The installed auth provider, for plugins that mint or look up credentials (chat). */
|
|
95
|
+
readonly auth?: AuthProvider | undefined;
|
|
96
|
+
/** `createServer` got an `auth` key whose value is undefined: a sign-in setup that failed to configure. */
|
|
97
|
+
readonly authMisconfigured?: boolean;
|
|
98
|
+
callerOf(request: Request): Promise<Caller>;
|
|
99
|
+
/**
|
|
100
|
+
* Whether the installed plugin `name` admits `caller`, for a plugin that serves another
|
|
101
|
+
* one (auth pairs computers for chat). True when it is not installed or has no policy.
|
|
102
|
+
*/
|
|
103
|
+
allows?(plugin: string, caller: PluginCaller): Promise<boolean>;
|
|
104
|
+
/**
|
|
105
|
+
* Resolves once the database holds every plugin's tables. Work a plugin starts on its own,
|
|
106
|
+
* such as a timer, waits for it; request handlers need not, as the server awaits it first.
|
|
107
|
+
*/
|
|
108
|
+
ready?(): Promise<void>;
|
|
109
|
+
/**
|
|
110
|
+
* Records a sync event for writes made outside an action's transaction, such as through
|
|
111
|
+
* a library that holds its own connection. With `tx`, the event commits with that
|
|
112
|
+
* transaction instead of its own. Does nothing when sync is off.
|
|
113
|
+
*/
|
|
114
|
+
announce(scope: string, tags: readonly Tag[], tx?: unknown): Promise<void>;
|
|
115
|
+
}
|
|
116
|
+
export {};
|
|
117
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AA2GA,+EAA+E;AAC/E,MAAM,UAAU,WAAW,CACzB,KAAqB;IAErB,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["import type {\n ActionErrorCode,\n ActionSource,\n AuthenticatedPrincipal,\n DataProvider,\n Principal,\n Tag,\n} from \"@parlor/core\";\nimport type { ActionRegistry } from \"@parlor/core/registry\";\nimport type { ServerChannel } from \"@parlor/sync\";\n\nimport type { CallerOf } from \"./access.js\";\nimport type { AuthProvider } from \"./auth.js\";\nimport type { Caller } from \"./caller.js\";\n\n/**\n * A framework feature the app installs with `createServer({ plugins })`. It owns the\n * tables prefixed `parlor_<name>_`, every path under `/_parlor/<name>/`, and the paths its\n * absolute routes declare.\n */\nexport interface ServerPlugin {\n readonly name: string;\n readonly migrations?: readonly Migration[] | undefined;\n setup(host: PluginHost): PluginRuntime;\n}\n\n/** Applied once per database in list order. An applied id must never change. */\nexport interface Migration {\n readonly id: `${string}/${number}_${string}`;\n readonly sql: string;\n}\n\nexport interface PluginRuntime {\n /**\n * Served at `POST /_parlor/<plugin>/actions/<action>` through the same runner as the app's\n * actions, but never listed on MCP and never callable by an agent.\n */\n readonly actions?: ActionRegistry | undefined;\n readonly channel?: ServerChannel | undefined;\n readonly routes?: readonly AnyPluginRoute[] | undefined;\n /** Called once per action call on every surface after it settles, whatever the outcome. */\n audit?(record: ActionAudit): void;\n /**\n * Starts the plugin's background work, such as timers. Called once, when the server is\n * ready for its first request: some runtimes allow no timers while the app loads.\n */\n start?(): void;\n /**\n * Who may use the plugin. Everyone else gets `forbidden` from its actions and signed-in\n * routes and never joins its channel. Absent admits whoever those surfaces admit.\n */\n allows?(caller: PluginCaller): boolean | Promise<boolean>;\n /** Runs before `close()` awaits in-flight requests, so it must end what it holds open. */\n close?(): void | Promise<void>;\n}\n\n/** Who is asking: enough to look the user up, with no request to read. */\nexport type PluginCaller = Pick<Caller, \"principal\" | \"scope\">;\n\nexport interface ActionAudit {\n readonly at: number;\n readonly action: string;\n readonly principal: Principal;\n readonly source: ActionSource;\n readonly scope: string;\n /** SHA-256 of the input as received; the input itself is not kept. */\n readonly inputDigest: string;\n /** `ran` once `run` started; `refused` when the call stopped before it. */\n readonly stage: \"refused\" | \"ran\";\n readonly outcome: \"ok\" | \"cancelled\" | ActionErrorCode;\n readonly confirmation?: ConfirmationAnswer | undefined;\n}\n\nexport type ConfirmationAnswer = \"approved\" | \"declined\" | \"timeout\" | \"unavailable\";\n\ntype SignedInKind = AuthenticatedPrincipal[\"kind\"];\n\n/**\n * A plain route with no transaction or sync event. `access` decides who may call it and\n * types the caller its handler receives. An anonymous caller is admitted only when `access`\n * lists it and no enforcing auth provider is installed.\n */\nexport interface PluginRoute<K extends SignedInKind | \"anonymous\"> {\n readonly method: \"GET\" | \"POST\";\n readonly path: `/${string}`;\n /**\n * Serves `path` as is from the origin root instead of under `/_parlor/<plugin>/`, for URLs\n * fixed outside the app, such as a payment provider's webhook. The path must be static.\n */\n readonly absolute?: boolean | undefined;\n readonly access: readonly K[];\n handle(request: Request, caller: CallerOf<K>): Promise<Response>;\n}\n\n/** Callable by anyone, signed in or not: sign-in pages, OAuth endpoints. */\nexport interface PublicPluginRoute {\n readonly method: \"GET\" | \"POST\";\n /** Absolute when it starts with `/.well-known/`. */\n readonly path: `/${string}`;\n /** See `PluginRoute.absolute`. */\n readonly absolute?: boolean | undefined;\n readonly access: \"public\";\n handle(request: Request): Promise<Response>;\n}\n\nexport type AnyPluginRoute = PluginRoute<SignedInKind | \"anonymous\"> | PublicPluginRoute;\n\n/** Infers `K` from `access`, so the handler's caller type follows the list. */\nexport function pluginRoute<const K extends SignedInKind | \"anonymous\">(\n route: PluginRoute<K>,\n): PluginRoute<K> {\n return route;\n}\n\nexport interface PluginHost {\n readonly basePath: string;\n readonly database: DataProvider | undefined;\n /** The installed auth provider, for plugins that mint or look up credentials (chat). */\n readonly auth?: AuthProvider | undefined;\n /** `createServer` got an `auth` key whose value is undefined: a sign-in setup that failed to configure. */\n readonly authMisconfigured?: boolean;\n callerOf(request: Request): Promise<Caller>;\n /**\n * Whether the installed plugin `name` admits `caller`, for a plugin that serves another\n * one (auth pairs computers for chat). True when it is not installed or has no policy.\n */\n allows?(plugin: string, caller: PluginCaller): Promise<boolean>;\n /**\n * Resolves once the database holds every plugin's tables. Work a plugin starts on its own,\n * such as a timer, waits for it; request handlers need not, as the server awaits it first.\n */\n ready?(): Promise<void>;\n /**\n * Records a sync event for writes made outside an action's transaction, such as through\n * a library that holds its own connection. With `tx`, the event commits with that\n * transaction instead of its own. Does nothing when sync is off.\n */\n announce(scope: string, tags: readonly Tag[], tx?: unknown): Promise<void>;\n}\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { UiManifest } from "@parlor/agent-ui";
|
|
2
|
+
import type { ActionDescriptor } from "@parlor/core/registry";
|
|
3
|
+
export declare const PROTOCOL_VERSION = 1;
|
|
4
|
+
export declare const DEFAULT_BASE_PATH = "/_parlor";
|
|
5
|
+
export declare const SOURCE_HEADER = "x-parlor-source";
|
|
6
|
+
export declare const CLIENT_HEADER = "x-parlor-client";
|
|
7
|
+
/** A native shell reads its bearer session from this response header after signing in. */
|
|
8
|
+
export declare const SESSION_TOKEN_HEADER = "set-auth-token";
|
|
9
|
+
export interface Manifest {
|
|
10
|
+
readonly protocol: typeof PROTOCOL_VERSION;
|
|
11
|
+
/** What a pairing host shows locally; filled once the server knows the app's name. */
|
|
12
|
+
readonly app?: {
|
|
13
|
+
readonly name: string;
|
|
14
|
+
} | undefined;
|
|
15
|
+
readonly actions: readonly ActionDescriptor[];
|
|
16
|
+
readonly ui?: UiManifest | undefined;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,eAAO,MAAM,iBAAiB,aAAa,CAAC;AAC5C,eAAO,MAAM,aAAa,oBAAoB,CAAC;AAC/C,eAAO,MAAM,aAAa,oBAAoB,CAAC;AAC/C,0FAA0F;AAC1F,eAAO,MAAM,oBAAoB,mBAAmB,CAAC;AAErD,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,QAAQ,EAAE,OAAO,gBAAgB,CAAC;IAC3C,sFAAsF;IACtF,QAAQ,CAAC,GAAG,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IACrD,QAAQ,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC9C,QAAQ,CAAC,EAAE,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;CACtC"}
|
package/dist/protocol.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export const PROTOCOL_VERSION = 1;
|
|
2
|
+
export const DEFAULT_BASE_PATH = "/_parlor";
|
|
3
|
+
export const SOURCE_HEADER = "x-parlor-source";
|
|
4
|
+
export const CLIENT_HEADER = "x-parlor-client";
|
|
5
|
+
/** A native shell reads its bearer session from this response header after signing in. */
|
|
6
|
+
export const SESSION_TOKEN_HEADER = "set-auth-token";
|
|
7
|
+
//# sourceMappingURL=protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAClC,MAAM,CAAC,MAAM,iBAAiB,GAAG,UAAU,CAAC;AAC5C,MAAM,CAAC,MAAM,aAAa,GAAG,iBAAiB,CAAC;AAC/C,MAAM,CAAC,MAAM,aAAa,GAAG,iBAAiB,CAAC;AAC/C,0FAA0F;AAC1F,MAAM,CAAC,MAAM,oBAAoB,GAAG,gBAAgB,CAAC","sourcesContent":["import type { UiManifest } from \"@parlor/agent-ui\";\nimport type { ActionDescriptor } from \"@parlor/core/registry\";\n\nexport const PROTOCOL_VERSION = 1;\nexport const DEFAULT_BASE_PATH = \"/_parlor\";\nexport const SOURCE_HEADER = \"x-parlor-source\";\nexport const CLIENT_HEADER = \"x-parlor-client\";\n/** A native shell reads its bearer session from this response header after signing in. */\nexport const SESSION_TOKEN_HEADER = \"set-auth-token\";\n\nexport interface Manifest {\n readonly protocol: typeof PROTOCOL_VERSION;\n /** What a pairing host shows locally; filled once the server knows the app's name. */\n readonly app?: { readonly name: string } | undefined;\n readonly actions: readonly ActionDescriptor[];\n readonly ui?: UiManifest | undefined;\n}\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How long a revocation is remembered. Whatever it revokes must stop verifying within
|
|
3
|
+
* this long, or the revocation is forgotten while the credential still works.
|
|
4
|
+
*/
|
|
5
|
+
export declare const REVOCATION_HORIZON_MS: number;
|
|
6
|
+
//# sourceMappingURL=revocation-horizon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"revocation-horizon.d.ts","sourceRoot":"","sources":["../src/revocation-horizon.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,qBAAqB,QAAc,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How long a revocation is remembered. Whatever it revokes must stop verifying within
|
|
3
|
+
* this long, or the revocation is forgotten while the credential still works.
|
|
4
|
+
*/
|
|
5
|
+
export const REVOCATION_HORIZON_MS = 11 * 60_000;
|
|
6
|
+
//# sourceMappingURL=revocation-horizon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"revocation-horizon.js","sourceRoot":"","sources":["../src/revocation-horizon.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,GAAG,MAAM,CAAC","sourcesContent":["/**\n * How long a revocation is remembered. Whatever it revokes must stop verifying within\n * this long, or the revocation is forgotten while the credential still works.\n */\nexport const REVOCATION_HORIZON_MS = 11 * 60_000;\n"]}
|
package/dist/scope.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type Principal } from "@parlor/core";
|
|
2
|
+
/** The tenant a request belongs to. Called once per request. */
|
|
3
|
+
export type ScopeResolver = (request: Request, principal: Principal) => string | Promise<string>;
|
|
4
|
+
export declare const DEFAULT_SCOPE = "default";
|
|
5
|
+
export declare const defaultScope: ScopeResolver;
|
|
6
|
+
//# sourceMappingURL=scope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAU,MAAM,cAAc,CAAC;AAEtD,gEAAgE;AAChE,MAAM,MAAM,aAAa,GAAG,CAC1B,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,SAAS,KACjB,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAE9B,eAAO,MAAM,aAAa,YAAY,CAAC;AAEvC,eAAO,MAAM,YAAY,EAAE,aACS,CAAC"}
|
package/dist/scope.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.js","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,MAAM,EAAE,MAAM,cAAc,CAAC;AAQtD,MAAM,CAAC,MAAM,aAAa,GAAG,SAAS,CAAC;AAEvC,MAAM,CAAC,MAAM,YAAY,GAAkB,CAAC,QAAQ,EAAE,SAAS,EAAE,EAAE,CACjE,MAAM,CAAC,SAAS,CAAC,IAAI,aAAa,CAAC","sourcesContent":["import { type Principal, userOf } from \"@parlor/core\";\n\n/** The tenant a request belongs to. Called once per request. */\nexport type ScopeResolver = (\n request: Request,\n principal: Principal,\n) => string | Promise<string>;\n\nexport const DEFAULT_SCOPE = \"default\";\n\nexport const defaultScope: ScopeResolver = (_request, principal) =>\n userOf(principal) ?? DEFAULT_SCOPE;\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,44 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parlor/server",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"homepage": "https://cychien.github.io/parlor",
|
|
5
|
+
"bugs": "https://github.com/cychien/parlor/issues",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/cychien/parlor.git",
|
|
10
|
+
"directory": "packages/server"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist"
|
|
14
|
+
],
|
|
15
|
+
"type": "module",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"import": "./dist/index.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@modelcontextprotocol/server": "^2.3.1",
|
|
24
|
+
"drizzle-orm": "^0.45.4",
|
|
25
|
+
"h3": "^2.0.1",
|
|
26
|
+
"zod": "^4.6.5",
|
|
27
|
+
"@parlor/core": "0.2.0",
|
|
28
|
+
"@parlor/agent-ui": "0.2.0",
|
|
29
|
+
"@parlor/sync": "0.2.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@modelcontextprotocol/client": "^2.3.1",
|
|
33
|
+
"@types/node": "^24.14.0",
|
|
34
|
+
"srvx": "^1.0.5",
|
|
35
|
+
"typescript": "^7.0.2",
|
|
36
|
+
"vitest": "^5.0.3",
|
|
37
|
+
"@parlor/data": "0.2.0"
|
|
38
|
+
},
|
|
39
|
+
"scripts": {
|
|
40
|
+
"build": "tsc -p tsconfig.json",
|
|
41
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
42
|
+
"test": "vitest run"
|
|
43
|
+
}
|
|
6
44
|
}
|