@segmentstream-cloud/ontology 0.10.0 → 0.11.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/action.d.ts +19 -0
- package/dist/action.js +1 -0
- package/dist/analyze.d.ts +3 -1
- package/dist/analyze.js +81 -1
- package/dist/bin/migrate.js +3 -2
- package/dist/diagnostics.d.ts +3 -3
- package/dist/diagnostics.js +1 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.js +4 -1
- package/dist/manifest.d.ts +48 -0
- package/dist/manifest.js +9 -0
- package/dist/migrate/apply.d.ts +7 -0
- package/dist/migrate/apply.js +18 -1
- package/dist/migrate/index.d.ts +1 -1
- package/dist/migrate/index.js +1 -1
- package/dist/migrate/model.d.ts +8 -0
- package/dist/migrate/plan.d.ts +6 -0
- package/dist/migrate/plan.js +10 -2
- package/dist/migrate/storage.d.ts +12 -0
- package/dist/migrate/storage.js +82 -0
- package/dist/names.d.ts +9 -1
- package/dist/names.js +11 -0
- package/dist/nitro.d.ts +13 -0
- package/dist/nitro.js +18 -0
- package/dist/runtime/generated-actions.d.ts +3 -0
- package/dist/runtime/generated-actions.js +3 -2
- package/dist/runtime/oauth.d.ts +9 -0
- package/dist/runtime/oauth.js +165 -0
- package/dist/runtime/principals.d.ts +5 -0
- package/dist/runtime/principals.js +15 -0
- package/dist/runtime/service-binding.js +2 -0
- package/dist/service/api.js +4 -10
- package/dist/service/authentication.d.ts +27 -1
- package/dist/service/authentication.js +48 -26
- package/dist/service/config.d.ts +5 -0
- package/dist/service/descriptions.d.ts +8 -0
- package/dist/service/descriptions.js +15 -0
- package/dist/service/errors.d.ts +5 -1
- package/dist/service/errors.js +6 -2
- package/dist/service/handlers.d.ts +1 -4
- package/dist/service/handlers.js +20 -203
- package/dist/service/mcp/server.d.ts +24 -0
- package/dist/service/mcp/server.js +370 -0
- package/dist/service/mcp/tools.d.ts +47 -0
- package/dist/service/mcp/tools.js +218 -0
- package/dist/service/oauth/protocol.d.ts +52 -0
- package/dist/service/oauth/protocol.js +110 -0
- package/dist/service/oauth/server.d.ts +27 -0
- package/dist/service/oauth/server.js +576 -0
- package/dist/service/operations.d.ts +114 -0
- package/dist/service/operations.js +218 -0
- package/dist/service/runtime-contract.d.ts +89 -0
- package/dist/service/schemas.d.ts +8 -0
- package/dist/service/service.d.ts +3 -3
- package/dist/service/service.js +10 -5
- package/package.json +6 -1
package/dist/action.d.ts
CHANGED
|
@@ -17,6 +17,17 @@ export interface ActionContext<Input, Prepared = undefined> extends PrepareConte
|
|
|
17
17
|
}
|
|
18
18
|
/** What `prepare` may fail with: the action errors, and connection calls that failed. */
|
|
19
19
|
export type PrepareError = ActionError | ConnectionError;
|
|
20
|
+
/**
|
|
21
|
+
* How an action behaves, as MCP tool annotations tell agents. Clients such as Claude ask the user
|
|
22
|
+
* before they run a destructive tool. Without hints an action is taken as destructive and not
|
|
23
|
+
* idempotent.
|
|
24
|
+
*/
|
|
25
|
+
export interface ActionHints {
|
|
26
|
+
/** Whether the action may overwrite or remove what someone decided. Default true. */
|
|
27
|
+
readonly destructive?: boolean;
|
|
28
|
+
/** Whether running it again with the same input changes nothing more. Default false. */
|
|
29
|
+
readonly idempotent?: boolean;
|
|
30
|
+
}
|
|
20
31
|
/** A described, typed, permissioned Effect function: the only way to change records. */
|
|
21
32
|
export interface Action<Input extends Schema.Top = Schema.Top, Result = unknown> {
|
|
22
33
|
readonly [ActionTypeId]: typeof ActionTypeId;
|
|
@@ -27,6 +38,8 @@ export interface Action<Input extends Schema.Top = Schema.Top, Result = unknown>
|
|
|
27
38
|
* is not set, the action requires `<entity>:<action name>`, for example `lead:changeStatus`.
|
|
28
39
|
*/
|
|
29
40
|
readonly permission: string | undefined;
|
|
41
|
+
/** How the action behaves, as `action({ hints })` set it; see {@link ActionHints}. */
|
|
42
|
+
readonly hints: ActionHints | undefined;
|
|
30
43
|
/** The connections `prepare` may call; empty for an action without `prepare`. */
|
|
31
44
|
readonly connections: ReadonlyArray<AnyConnectionHandle>;
|
|
32
45
|
/**
|
|
@@ -64,6 +77,12 @@ interface ActionOptions<Input extends Schema.Top> {
|
|
|
64
77
|
* Roles grant it in their `permissions`.
|
|
65
78
|
*/
|
|
66
79
|
readonly permission?: string;
|
|
80
|
+
/**
|
|
81
|
+
* How the action behaves, for the agents that run it over MCP. Set `destructive: false` for an
|
|
82
|
+
* action that only adds or that history makes easy to reverse, and `idempotent: true` for one
|
|
83
|
+
* that a repeated call leaves as it was.
|
|
84
|
+
*/
|
|
85
|
+
readonly hints?: ActionHints;
|
|
67
86
|
}
|
|
68
87
|
export interface ActionConfig<Input extends Schema.Top, Result> extends ActionOptions<Input> {
|
|
69
88
|
/**
|
package/dist/action.js
CHANGED
|
@@ -11,6 +11,7 @@ export function action(config) {
|
|
|
11
11
|
description: config.description,
|
|
12
12
|
input: config.input,
|
|
13
13
|
permission: config.permission,
|
|
14
|
+
hints: config.hints,
|
|
14
15
|
connections: config.connections ?? [],
|
|
15
16
|
...(config.prepare === undefined ? {} : { prepare: config.prepare }),
|
|
16
17
|
// A prepare-only action answers with what prepare returned; it writes nothing.
|
package/dist/analyze.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Schema } from "effect";
|
|
2
|
-
import { type Action } from "./action.js";
|
|
2
|
+
import { type Action, type ActionHints } from "./action.js";
|
|
3
3
|
import { type AnyConnectionHandle } from "./connection.js";
|
|
4
4
|
import type { Diagnostic } from "./diagnostics.js";
|
|
5
5
|
import { type AnyEntity } from "./entity.js";
|
|
@@ -67,6 +67,8 @@ export interface ResolvedAction {
|
|
|
67
67
|
readonly input: JsonSchemaObject | undefined;
|
|
68
68
|
/** The keys of the connections the action's `prepare` calls, in declaration order. */
|
|
69
69
|
readonly connections: ReadonlyArray<string>;
|
|
70
|
+
/** The hints the action declares, or `undefined` when it declares none. */
|
|
71
|
+
readonly hints: ActionHints | undefined;
|
|
70
72
|
}
|
|
71
73
|
/** A connection the ontology declares. */
|
|
72
74
|
export interface ResolvedConnection {
|
package/dist/analyze.js
CHANGED
|
@@ -5,7 +5,7 @@ import { BLOB_CONTENT_TYPES, MAX_BLOB_BYTES } from "./blob.js";
|
|
|
5
5
|
import { isAction } from "./action.js";
|
|
6
6
|
import { CONNECTION_KEY, isConnection } from "./connection.js";
|
|
7
7
|
import { isEntity } from "./entity.js";
|
|
8
|
-
import { LEGACY_MEMBER_NAME, ENTITY_ID, GENERATED_ACTIONS, GENERATED_UPSERT_PREFIX, HISTORY_SUFFIX, MEMBER_ROLE, RESERVED_ENTITY_NAMES, RESERVED_MEMBER_NAMES, RESERVED_RELATIONSHIP_NAMES, SNAKE_CASE_NAME, SYSTEM_PROPERTIES, isSystemProperty, } from "./names.js";
|
|
8
|
+
import { LEGACY_MEMBER_NAME, ENTITY_ID, GENERATED_ACTIONS, GENERATED_UPSERT_PREFIX, HISTORY_SUFFIX, MCP_READ_TOOLS, MCP_TOOL_NAME_MAX_LENGTH, MEMBER_ROLE, mcpToolName, RESERVED_ENTITY_NAMES, RESERVED_MEMBER_NAMES, RESERVED_RELATIONSHIP_NAMES, SNAKE_CASE_NAME, SYSTEM_PROPERTIES, isSystemProperty, } from "./names.js";
|
|
9
9
|
import { REFERENCE_ANNOTATION, propertyDefinition, referenceTarget, } from "./property.js";
|
|
10
10
|
import { generatedActionPermissions, parsePermission, permissionOf, READ_VERB, rolesGranting, WILDCARD, } from "./permissions.js";
|
|
11
11
|
import { ON_DELETE, isRelationship } from "./relationship.js";
|
|
@@ -58,6 +58,7 @@ export function analyze(config, options = {}) {
|
|
|
58
58
|
const resolved = entities.map((candidate) => resolveEntity(candidate, scope));
|
|
59
59
|
checkEntityIdentities(resolved, report);
|
|
60
60
|
checkMemberNames(resolved, report);
|
|
61
|
+
checkToolNames(resolved, report);
|
|
61
62
|
checkWarehouseSource(resolved, report);
|
|
62
63
|
checkConnectionsUsed(resolved, connections, config.connections ?? [], report);
|
|
63
64
|
if (options.checkPermissions !== false) {
|
|
@@ -65,6 +66,58 @@ export function analyze(config, options = {}) {
|
|
|
65
66
|
}
|
|
66
67
|
return { entities: resolved, roles, signIn, connections, diagnostics };
|
|
67
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* The operations of a stored entity that become MCP tools, each with the path a problem is reported
|
|
71
|
+
* at: the reads, the generated actions and the authored actions.
|
|
72
|
+
*/
|
|
73
|
+
function toolOperations(candidate) {
|
|
74
|
+
const { permissions } = candidate;
|
|
75
|
+
const generated = [
|
|
76
|
+
...(permissions.create !== undefined ? ["create", "update", "delete"] : []),
|
|
77
|
+
...(permissions.create !== undefined
|
|
78
|
+
? candidate.properties
|
|
79
|
+
.filter(({ definition }) => definition.unique)
|
|
80
|
+
.map(({ name }) => `${GENERATED_UPSERT_PREFIX}${name}`)
|
|
81
|
+
: []),
|
|
82
|
+
...(permissions.link !== undefined ? ["link", "unlink"] : []),
|
|
83
|
+
];
|
|
84
|
+
return [
|
|
85
|
+
...[...MCP_READ_TOOLS, ...generated].map((operation) => ({ operation, path: candidate.name })),
|
|
86
|
+
// An authored action with a generated action's name is already refused as a reserved name.
|
|
87
|
+
...candidate.actions
|
|
88
|
+
.filter(({ name }) => !GENERATED_ACTIONS.includes(name) && !GENERATED_UPSERT.test(name))
|
|
89
|
+
.map(({ name }) => ({ operation: name, path: `${candidate.name}.actions.${name}` })),
|
|
90
|
+
];
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Every MCP tool needs a name of its own, at most 64 characters long. A tool's name joins the
|
|
94
|
+
* entity's and the operation's with an underscore, so entity `pilot` with an action `request_find`
|
|
95
|
+
* would take the name of entity `pilot_request`'s `find`.
|
|
96
|
+
*/
|
|
97
|
+
function checkToolNames(entities, report) {
|
|
98
|
+
const owners = new Map();
|
|
99
|
+
const seen = new Set();
|
|
100
|
+
for (const candidate of entities) {
|
|
101
|
+
// A second entity with the same name is already refused as a duplicate.
|
|
102
|
+
if (candidate.entity.definition.source !== undefined || seen.has(candidate.name)) {
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
seen.add(candidate.name);
|
|
106
|
+
for (const { operation, path } of toolOperations(candidate)) {
|
|
107
|
+
const name = mcpToolName(candidate.name, operation);
|
|
108
|
+
const owner = owners.get(name);
|
|
109
|
+
if (owner !== undefined) {
|
|
110
|
+
report("invalid-tool-name", path, `its MCP tool ${name} is already the tool of ${owner}; rename one of them.`);
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
owners.set(name, `${candidate.name}'s ${operation}`);
|
|
114
|
+
if (name.length > MCP_TOOL_NAME_MAX_LENGTH) {
|
|
115
|
+
report("invalid-tool-name", path, `its MCP tool ${name} is ${name.length} characters long; agents accept at most ` +
|
|
116
|
+
`${MCP_TOOL_NAME_MAX_LENGTH}. Shorten the entity or the action name.`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
68
121
|
/** The handles `defineOntology({ connections })` lists, each with a valid key and a description. */
|
|
69
122
|
function collectConnections(config, report) {
|
|
70
123
|
const declared = config.connections;
|
|
@@ -546,10 +599,37 @@ function resolveActions(candidate, scope) {
|
|
|
546
599
|
permission: resolvePermission(path, permissionOf(candidate.name, name), action, scope),
|
|
547
600
|
input: resolveInput(path, action.input, scope),
|
|
548
601
|
connections: resolveActionConnections(path, action, scope),
|
|
602
|
+
hints: resolveHints(path, action, report),
|
|
549
603
|
});
|
|
550
604
|
}
|
|
551
605
|
return actions;
|
|
552
606
|
}
|
|
607
|
+
const HINT_NAMES = ["destructive", "idempotent"];
|
|
608
|
+
/** The action's `hints`: an object of booleans, `destructive` and `idempotent`. */
|
|
609
|
+
function resolveHints(path, action, report) {
|
|
610
|
+
const declared = action.hints;
|
|
611
|
+
if (declared === undefined) {
|
|
612
|
+
return undefined;
|
|
613
|
+
}
|
|
614
|
+
const at = `${path}.hints`;
|
|
615
|
+
if (!isPlainObject(declared)) {
|
|
616
|
+
report("invalid-action", at, "hints is an object such as { destructive: false }.");
|
|
617
|
+
return undefined;
|
|
618
|
+
}
|
|
619
|
+
const hints = {};
|
|
620
|
+
for (const [key, value] of Object.entries(declared)) {
|
|
621
|
+
if (!HINT_NAMES.includes(key)) {
|
|
622
|
+
report("invalid-action", `${at}.${key}`, `is not a hint; use ${HINT_NAMES.join(" or ")}.`);
|
|
623
|
+
}
|
|
624
|
+
else if (typeof value !== "boolean") {
|
|
625
|
+
report("invalid-action", `${at}.${key}`, "is true or false.");
|
|
626
|
+
}
|
|
627
|
+
else {
|
|
628
|
+
hints[key] = value;
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
return hints;
|
|
632
|
+
}
|
|
553
633
|
/** The action's own `permission`, which names an entity and a verb without wildcards. */
|
|
554
634
|
function resolvePermission(path, fallback, action, scope) {
|
|
555
635
|
const declared = action.permission;
|
package/dist/bin/migrate.js
CHANGED
|
@@ -2,7 +2,7 @@ import * as PgClient from "@effect/sql-pg/PgClient";
|
|
|
2
2
|
import { Cause, Effect, Redacted } from "effect";
|
|
3
3
|
import { SqlClient } from "effect/unstable/sql";
|
|
4
4
|
import { isSqlError } from "effect/unstable/sql/SqlError";
|
|
5
|
-
import { applyMigration, readCatalog } from "../migrate/apply.js";
|
|
5
|
+
import { applyMigration, readCatalog, readRuntimeTables, } from "../migrate/apply.js";
|
|
6
6
|
import { MigrationRefused } from "../migrate/errors.js";
|
|
7
7
|
import { isNoopMigration } from "../migrate/model.js";
|
|
8
8
|
import { planMigration } from "../migrate/plan.js";
|
|
@@ -88,7 +88,8 @@ function migrateDatabase(input) {
|
|
|
88
88
|
return Effect.gen(function* () {
|
|
89
89
|
const sql = yield* SqlClient.SqlClient;
|
|
90
90
|
const current = yield* readCatalog({ sql });
|
|
91
|
-
const
|
|
91
|
+
const existingTables = yield* readRuntimeTables({ sql });
|
|
92
|
+
const plan = planMigration({ current, target, existingTables });
|
|
92
93
|
output.stdout(formatPlan(plan, { sql: input.planOnly }));
|
|
93
94
|
if (plan.refusals.length > 0) {
|
|
94
95
|
output.stderr(formatRefusals(plan.refusals));
|
package/dist/diagnostics.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Schema } from "effect";
|
|
2
|
-
export declare const DIAGNOSTIC_CODES: readonly ["invalid-source", "missing-column", "invalid-column", "invalid-scope", "source-with-actions", "source-with-index", "invalid-measure", "unknown-measure", "circular-measure", "invalid-join", "missing-join", "invalid-entity", "invalid-property", "invalid-relationship", "invalid-actions", "invalid-action", "invalid-action-input", "invalid-role", "invalid-name", "reserved-name", "duplicate-name", "invalid-entity-id", "duplicate-entity-id", "missing-label", "missing-description", "invalid-title", "invalid-options", "invalid-default", "invalid-constraint", "unknown-relationship-target", "inverse-collision", "invalid-on-delete", "invalid-phrase", "invalid-index", "unknown-reference", "invalid-renamed-from", "invalid-guide", "managed-without-effect", "missing-permissions", "invalid-permission", "unknown-permission", "removed-allow", "unreachable-action", "wildcard-permission", "invalid-sign-in", "invalid-connection", "unknown-connection", "unused-connection", "invalid-prepare"];
|
|
2
|
+
export declare const DIAGNOSTIC_CODES: readonly ["invalid-source", "missing-column", "invalid-column", "invalid-scope", "source-with-actions", "source-with-index", "invalid-measure", "unknown-measure", "circular-measure", "invalid-join", "missing-join", "invalid-entity", "invalid-property", "invalid-relationship", "invalid-actions", "invalid-action", "invalid-action-input", "invalid-role", "invalid-name", "reserved-name", "duplicate-name", "invalid-entity-id", "duplicate-entity-id", "missing-label", "missing-description", "invalid-title", "invalid-options", "invalid-default", "invalid-constraint", "unknown-relationship-target", "inverse-collision", "invalid-on-delete", "invalid-phrase", "invalid-index", "unknown-reference", "invalid-renamed-from", "invalid-guide", "managed-without-effect", "missing-permissions", "invalid-permission", "unknown-permission", "removed-allow", "unreachable-action", "wildcard-permission", "invalid-sign-in", "invalid-connection", "unknown-connection", "unused-connection", "invalid-prepare", "invalid-tool-name"];
|
|
3
3
|
export type DiagnosticCode = (typeof DIAGNOSTIC_CODES)[number];
|
|
4
4
|
/** A problem `check` found in an ontology definition. */
|
|
5
5
|
export declare const Diagnostic: Schema.Struct<{
|
|
6
6
|
readonly severity: Schema.Literals<readonly ["error", "warning"]>;
|
|
7
|
-
readonly code: Schema.Literals<readonly ["invalid-source", "missing-column", "invalid-column", "invalid-scope", "source-with-actions", "source-with-index", "invalid-measure", "unknown-measure", "circular-measure", "invalid-join", "missing-join", "invalid-entity", "invalid-property", "invalid-relationship", "invalid-actions", "invalid-action", "invalid-action-input", "invalid-role", "invalid-name", "reserved-name", "duplicate-name", "invalid-entity-id", "duplicate-entity-id", "missing-label", "missing-description", "invalid-title", "invalid-options", "invalid-default", "invalid-constraint", "unknown-relationship-target", "inverse-collision", "invalid-on-delete", "invalid-phrase", "invalid-index", "unknown-reference", "invalid-renamed-from", "invalid-guide", "managed-without-effect", "missing-permissions", "invalid-permission", "unknown-permission", "removed-allow", "unreachable-action", "wildcard-permission", "invalid-sign-in", "invalid-connection", "unknown-connection", "unused-connection", "invalid-prepare"]>;
|
|
7
|
+
readonly code: Schema.Literals<readonly ["invalid-source", "missing-column", "invalid-column", "invalid-scope", "source-with-actions", "source-with-index", "invalid-measure", "unknown-measure", "circular-measure", "invalid-join", "missing-join", "invalid-entity", "invalid-property", "invalid-relationship", "invalid-actions", "invalid-action", "invalid-action-input", "invalid-role", "invalid-name", "reserved-name", "duplicate-name", "invalid-entity-id", "duplicate-entity-id", "missing-label", "missing-description", "invalid-title", "invalid-options", "invalid-default", "invalid-constraint", "unknown-relationship-target", "inverse-collision", "invalid-on-delete", "invalid-phrase", "invalid-index", "unknown-reference", "invalid-renamed-from", "invalid-guide", "managed-without-effect", "missing-permissions", "invalid-permission", "unknown-permission", "removed-allow", "unreachable-action", "wildcard-permission", "invalid-sign-in", "invalid-connection", "unknown-connection", "unused-connection", "invalid-prepare", "invalid-tool-name"]>;
|
|
8
8
|
/** Where the problem is, for example `lead.properties.status.options[1]`. */
|
|
9
9
|
readonly path: Schema.String;
|
|
10
10
|
readonly message: Schema.String;
|
|
@@ -14,7 +14,7 @@ declare const InvalidOntology_base: Schema.Class<InvalidOntology, Schema.TaggedS
|
|
|
14
14
|
readonly message: Schema.String;
|
|
15
15
|
readonly diagnostics: Schema.$Array<Schema.Struct<{
|
|
16
16
|
readonly severity: Schema.Literals<readonly ["error", "warning"]>;
|
|
17
|
-
readonly code: Schema.Literals<readonly ["invalid-source", "missing-column", "invalid-column", "invalid-scope", "source-with-actions", "source-with-index", "invalid-measure", "unknown-measure", "circular-measure", "invalid-join", "missing-join", "invalid-entity", "invalid-property", "invalid-relationship", "invalid-actions", "invalid-action", "invalid-action-input", "invalid-role", "invalid-name", "reserved-name", "duplicate-name", "invalid-entity-id", "duplicate-entity-id", "missing-label", "missing-description", "invalid-title", "invalid-options", "invalid-default", "invalid-constraint", "unknown-relationship-target", "inverse-collision", "invalid-on-delete", "invalid-phrase", "invalid-index", "unknown-reference", "invalid-renamed-from", "invalid-guide", "managed-without-effect", "missing-permissions", "invalid-permission", "unknown-permission", "removed-allow", "unreachable-action", "wildcard-permission", "invalid-sign-in", "invalid-connection", "unknown-connection", "unused-connection", "invalid-prepare"]>;
|
|
17
|
+
readonly code: Schema.Literals<readonly ["invalid-source", "missing-column", "invalid-column", "invalid-scope", "source-with-actions", "source-with-index", "invalid-measure", "unknown-measure", "circular-measure", "invalid-join", "missing-join", "invalid-entity", "invalid-property", "invalid-relationship", "invalid-actions", "invalid-action", "invalid-action-input", "invalid-role", "invalid-name", "reserved-name", "duplicate-name", "invalid-entity-id", "duplicate-entity-id", "missing-label", "missing-description", "invalid-title", "invalid-options", "invalid-default", "invalid-constraint", "unknown-relationship-target", "inverse-collision", "invalid-on-delete", "invalid-phrase", "invalid-index", "unknown-reference", "invalid-renamed-from", "invalid-guide", "managed-without-effect", "missing-permissions", "invalid-permission", "unknown-permission", "removed-allow", "unreachable-action", "wildcard-permission", "invalid-sign-in", "invalid-connection", "unknown-connection", "unused-connection", "invalid-prepare", "invalid-tool-name"]>;
|
|
18
18
|
/** Where the problem is, for example `lead.properties.status.options[1]`. */
|
|
19
19
|
readonly path: Schema.String;
|
|
20
20
|
readonly message: Schema.String;
|
package/dist/diagnostics.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export type { WarehouseSource } from "./source.js";
|
|
|
4
4
|
export { m } from "./measure.js";
|
|
5
5
|
export type { Measure, Measures, MeasureExpression, MeasureOptions } from "./measure.js";
|
|
6
6
|
export { action, isAction } from "./action.js";
|
|
7
|
-
export type { Action, ActionConfig, ActionConfigWithConnections, ActionContext, ActionEncodedInput, ActionInput, ActionResult, Actions, AnyAction, PrepareContext, PrepareError, } from "./action.js";
|
|
7
|
+
export type { Action, ActionConfig, ActionConfigWithConnections, ActionContext, ActionEncodedInput, ActionHints, ActionInput, ActionResult, Actions, AnyAction, PrepareContext, PrepareError, } from "./action.js";
|
|
8
8
|
export { CONNECTION_ERROR_REASONS, CONNECTION_KEY, CONNECTION_METHODS, connection, ConnectionError, Connections, ConnectionTransport, isConnection, MAXIMUM_CONNECTION_BODY_BYTES, } from "./connection.js";
|
|
9
9
|
export type { AnyConnectionHandle, Connection, ConnectionCall, ConnectionClient, ConnectionErrorReason, ConnectionHandle, ConnectionHeaders, ConnectionMethod, ConnectionOptions, ConnectionReply, ConnectionRequest, ConnectionRequestOptions, ConnectionResponse, ConnectionsOf, ConnectionStub, StubRequest, StubResponse, } from "./connection.js";
|
|
10
10
|
export type { EntityPermissions, JsonSchemaObject, MemberOptions, OntologyConfig, ResolvedAction, ResolvedConnection, ResolvedEntity, ResolvedIndex, ResolvedProperty, ResolvedRelationship, } from "./analyze.js";
|
|
@@ -55,10 +55,12 @@ export type { ConnectionAudit, ConnectionTransportFactory, LocalConnection, Loca
|
|
|
55
55
|
export { configFromEnv, ENVIRONMENT_VARIABLES, NEON_AUTH_ENVIRONMENT_VARIABLES, OntologyServiceConfigError, } from "./service/config.js";
|
|
56
56
|
export type { ActionCommitted, AfterCommitHook, NeonAuthEnvironment, OntologyEnvironment, OntologyServiceConfig, } from "./service/config.js";
|
|
57
57
|
export { NotInvited, OntologyBackend } from "./service/runtime-contract.js";
|
|
58
|
-
export type { GeneratedActionsProvider, IdentityProvider, OntologyServiceRuntime, RunActionInput, SignInIdentity, } from "./service/runtime-contract.js";
|
|
58
|
+
export type { GeneratedActionsProvider, IdentityProvider, OAuthClient, OAuthClientAuthMethod, OAuthGrant, OAuthRequest, OAuthStore, OAuthToken, OAuthTokenKind, OntologyServiceRuntime, RunActionInput, SignInIdentity, UsedOAuthToken, } from "./service/runtime-contract.js";
|
|
59
59
|
export { createOntologyService, ONTOLOGY_HASH_HEADER, REQUEST_ID_HEADER, } from "./service/service.js";
|
|
60
|
+
export { MCP_PATH, MCP_PROTOCOL_VERSIONS } from "./service/mcp/server.js";
|
|
61
|
+
export { MCP_TOOL_NAME_MAX_LENGTH, mcpToolName } from "./names.js";
|
|
60
62
|
export type { OntologyService } from "./service/service.js";
|
|
61
|
-
export { applyMigration, CatalogInvalid, CatalogMismatch, isNoopMigration, migrate, MIGRATION_REFUSAL_CODES, MIGRATION_STEP_CLASSIFICATIONS, MIGRATION_STEP_KINDS, MigrationFailed, MigrationPlan, MigrationRefusal, MigrationRefused, MigrationStep, OntologyStorage, planMigration, readCatalog, } from "./migrate/index.js";
|
|
63
|
+
export { applyMigration, CatalogInvalid, CatalogMismatch, isNoopMigration, migrate, MIGRATION_REFUSAL_CODES, MIGRATION_STEP_CLASSIFICATIONS, MIGRATION_STEP_KINDS, MigrationFailed, MigrationPlan, MigrationRefusal, MigrationRefused, MigrationStep, OntologyStorage, planMigration, readCatalog, readRuntimeTables, } from "./migrate/index.js";
|
|
62
64
|
export type { ApplyMigrationError, ApplyMigrationOptions, CatalogInput, MigrateInput, MigrationOptions, MigrationRefusalCode, MigrationResult, MigrationStepClassification, MigrationStepKind, PlanMigrationInput, } from "./migrate/index.js";
|
|
63
65
|
export type { BlobStorageBinding } from "./storage/provider.js";
|
|
64
66
|
export { runBlobStorageMaintenance } from "./storage/operator.js";
|
package/dist/index.js
CHANGED
|
@@ -34,6 +34,9 @@ export { deployedConnections, LocalConnectionContextError, localConnections, OID
|
|
|
34
34
|
export { configFromEnv, ENVIRONMENT_VARIABLES, NEON_AUTH_ENVIRONMENT_VARIABLES, OntologyServiceConfigError, } from "./service/config.js";
|
|
35
35
|
export { NotInvited, OntologyBackend } from "./service/runtime-contract.js";
|
|
36
36
|
export { createOntologyService, ONTOLOGY_HASH_HEADER, REQUEST_ID_HEADER, } from "./service/service.js";
|
|
37
|
+
// The MCP server the service serves beside the HTTP API.
|
|
38
|
+
export { MCP_PATH, MCP_PROTOCOL_VERSIONS } from "./service/mcp/server.js";
|
|
39
|
+
export { MCP_TOOL_NAME_MAX_LENGTH, mcpToolName } from "./names.js";
|
|
37
40
|
// Migrations: the planner, the applier and the physical mapping they share with the runtime.
|
|
38
|
-
export { applyMigration, CatalogInvalid, CatalogMismatch, isNoopMigration, migrate, MIGRATION_REFUSAL_CODES, MIGRATION_STEP_CLASSIFICATIONS, MIGRATION_STEP_KINDS, MigrationFailed, MigrationPlan, MigrationRefusal, MigrationRefused, MigrationStep, OntologyStorage, planMigration, readCatalog, } from "./migrate/index.js";
|
|
41
|
+
export { applyMigration, CatalogInvalid, CatalogMismatch, isNoopMigration, migrate, MIGRATION_REFUSAL_CODES, MIGRATION_STEP_CLASSIFICATIONS, MIGRATION_STEP_KINDS, MigrationFailed, MigrationPlan, MigrationRefusal, MigrationRefused, MigrationStep, OntologyStorage, planMigration, readCatalog, readRuntimeTables, } from "./migrate/index.js";
|
|
39
42
|
export { runBlobStorageMaintenance } from "./storage/operator.js";
|
package/dist/manifest.d.ts
CHANGED
|
@@ -85,6 +85,14 @@ export declare const ActionManifest: Schema.Struct<{
|
|
|
85
85
|
* when there are some; absent reads as none.
|
|
86
86
|
*/
|
|
87
87
|
readonly connections: Schema.optionalKey<Schema.$Array<Schema.String>>;
|
|
88
|
+
/**
|
|
89
|
+
* How the action behaves, as MCP tool annotations tell agents. Written only when the action
|
|
90
|
+
* declares hints; absent reads as destructive and not idempotent.
|
|
91
|
+
*/
|
|
92
|
+
readonly hints: Schema.optionalKey<Schema.Struct<{
|
|
93
|
+
readonly destructive: Schema.optionalKey<Schema.Boolean>;
|
|
94
|
+
readonly idempotent: Schema.optionalKey<Schema.Boolean>;
|
|
95
|
+
}>>;
|
|
88
96
|
}>;
|
|
89
97
|
export type ActionManifest = typeof ActionManifest.Type;
|
|
90
98
|
/**
|
|
@@ -186,6 +194,14 @@ export declare const EntityManifest: Schema.Struct<{
|
|
|
186
194
|
* when there are some; absent reads as none.
|
|
187
195
|
*/
|
|
188
196
|
readonly connections: Schema.optionalKey<Schema.$Array<Schema.String>>;
|
|
197
|
+
/**
|
|
198
|
+
* How the action behaves, as MCP tool annotations tell agents. Written only when the action
|
|
199
|
+
* declares hints; absent reads as destructive and not idempotent.
|
|
200
|
+
*/
|
|
201
|
+
readonly hints: Schema.optionalKey<Schema.Struct<{
|
|
202
|
+
readonly destructive: Schema.optionalKey<Schema.Boolean>;
|
|
203
|
+
readonly idempotent: Schema.optionalKey<Schema.Boolean>;
|
|
204
|
+
}>>;
|
|
189
205
|
}>>;
|
|
190
206
|
/** Always written; absent from version 1 manifests. */
|
|
191
207
|
readonly permissions: Schema.optionalKey<Schema.Struct<{
|
|
@@ -318,6 +334,14 @@ export declare const OntologyManifestWire: Schema.encodeKeys<Schema.Struct<{
|
|
|
318
334
|
* when there are some; absent reads as none.
|
|
319
335
|
*/
|
|
320
336
|
readonly connections: Schema.optionalKey<Schema.$Array<Schema.String>>;
|
|
337
|
+
/**
|
|
338
|
+
* How the action behaves, as MCP tool annotations tell agents. Written only when the action
|
|
339
|
+
* declares hints; absent reads as destructive and not idempotent.
|
|
340
|
+
*/
|
|
341
|
+
readonly hints: Schema.optionalKey<Schema.Struct<{
|
|
342
|
+
readonly destructive: Schema.optionalKey<Schema.Boolean>;
|
|
343
|
+
readonly idempotent: Schema.optionalKey<Schema.Boolean>;
|
|
344
|
+
}>>;
|
|
321
345
|
}>>;
|
|
322
346
|
/** Always written; absent from version 1 manifests. */
|
|
323
347
|
readonly permissions: Schema.optionalKey<Schema.Struct<{
|
|
@@ -453,6 +477,14 @@ export declare const OntologyManifest: Schema.Union<readonly [Schema.encodeKeys<
|
|
|
453
477
|
* when there are some; absent reads as none.
|
|
454
478
|
*/
|
|
455
479
|
readonly connections: Schema.optionalKey<Schema.$Array<Schema.String>>;
|
|
480
|
+
/**
|
|
481
|
+
* How the action behaves, as MCP tool annotations tell agents. Written only when the action
|
|
482
|
+
* declares hints; absent reads as destructive and not idempotent.
|
|
483
|
+
*/
|
|
484
|
+
readonly hints: Schema.optionalKey<Schema.Struct<{
|
|
485
|
+
readonly destructive: Schema.optionalKey<Schema.Boolean>;
|
|
486
|
+
readonly idempotent: Schema.optionalKey<Schema.Boolean>;
|
|
487
|
+
}>>;
|
|
456
488
|
}>>;
|
|
457
489
|
/** Always written; absent from version 1 manifests. */
|
|
458
490
|
readonly permissions: Schema.optionalKey<Schema.Struct<{
|
|
@@ -582,6 +614,14 @@ export declare const OntologyManifest: Schema.Union<readonly [Schema.encodeKeys<
|
|
|
582
614
|
* when there are some; absent reads as none.
|
|
583
615
|
*/
|
|
584
616
|
readonly connections: Schema.optionalKey<Schema.$Array<Schema.String>>;
|
|
617
|
+
/**
|
|
618
|
+
* How the action behaves, as MCP tool annotations tell agents. Written only when the action
|
|
619
|
+
* declares hints; absent reads as destructive and not idempotent.
|
|
620
|
+
*/
|
|
621
|
+
readonly hints: Schema.optionalKey<Schema.Struct<{
|
|
622
|
+
readonly destructive: Schema.optionalKey<Schema.Boolean>;
|
|
623
|
+
readonly idempotent: Schema.optionalKey<Schema.Boolean>;
|
|
624
|
+
}>>;
|
|
585
625
|
}>>;
|
|
586
626
|
/** Always written; absent from version 1 manifests. */
|
|
587
627
|
readonly permissions: Schema.optionalKey<Schema.Struct<{
|
|
@@ -629,6 +669,10 @@ export declare const decodeManifestDocument: (value: unknown) => Effect.Effect<{
|
|
|
629
669
|
};
|
|
630
670
|
readonly permission?: string | undefined;
|
|
631
671
|
readonly connections?: readonly string[] | undefined;
|
|
672
|
+
readonly hints?: {
|
|
673
|
+
readonly destructive?: boolean | undefined;
|
|
674
|
+
readonly idempotent?: boolean | undefined;
|
|
675
|
+
} | undefined;
|
|
632
676
|
}[];
|
|
633
677
|
readonly title: string;
|
|
634
678
|
readonly properties: readonly {
|
|
@@ -729,6 +773,10 @@ export declare const decodeManifestDocument: (value: unknown) => Effect.Effect<{
|
|
|
729
773
|
};
|
|
730
774
|
readonly permission?: string | undefined;
|
|
731
775
|
readonly connections?: readonly string[] | undefined;
|
|
776
|
+
readonly hints?: {
|
|
777
|
+
readonly destructive?: boolean | undefined;
|
|
778
|
+
readonly idempotent?: boolean | undefined;
|
|
779
|
+
} | undefined;
|
|
732
780
|
}[];
|
|
733
781
|
readonly title: string;
|
|
734
782
|
readonly properties: readonly {
|
package/dist/manifest.js
CHANGED
|
@@ -79,6 +79,14 @@ export const ActionManifest = Schema.Struct({
|
|
|
79
79
|
* when there are some; absent reads as none.
|
|
80
80
|
*/
|
|
81
81
|
connections: Schema.optionalKey(Schema.Array(Schema.String)),
|
|
82
|
+
/**
|
|
83
|
+
* How the action behaves, as MCP tool annotations tell agents. Written only when the action
|
|
84
|
+
* declares hints; absent reads as destructive and not idempotent.
|
|
85
|
+
*/
|
|
86
|
+
hints: Schema.optionalKey(Schema.Struct({
|
|
87
|
+
destructive: Schema.optionalKey(Schema.Boolean),
|
|
88
|
+
idempotent: Schema.optionalKey(Schema.Boolean),
|
|
89
|
+
})),
|
|
82
90
|
});
|
|
83
91
|
/**
|
|
84
92
|
* The permissions of an entity's reads and generated actions, so that readers need not rebuild the
|
|
@@ -352,6 +360,7 @@ function entityManifest(resolved) {
|
|
|
352
360
|
permission: action.permission,
|
|
353
361
|
input: action.input ?? {},
|
|
354
362
|
...(action.connections.length > 0 ? { connections: [...action.connections] } : {}),
|
|
363
|
+
...(action.hints !== undefined ? { hints: { ...action.hints } } : {}),
|
|
355
364
|
})),
|
|
356
365
|
permissions: { ...resolved.permissions },
|
|
357
366
|
};
|
package/dist/migrate/apply.d.ts
CHANGED
|
@@ -54,6 +54,13 @@ export declare const applyMigration: (plan: MigrationPlan, options: ApplyMigrati
|
|
|
54
54
|
* workspace database first as a dry run, then on production: the plan is made against each database's
|
|
55
55
|
* own catalog.
|
|
56
56
|
*/
|
|
57
|
+
/** The runtime's tables, beside the catalog and the entity tables. */
|
|
58
|
+
export declare const RUNTIME_TABLES: ReadonlyArray<string>;
|
|
59
|
+
/**
|
|
60
|
+
* The runtime tables the database has, for `planMigration`'s `existingTables`: a database that an
|
|
61
|
+
* earlier SDK migrated lacks the tables added since.
|
|
62
|
+
*/
|
|
63
|
+
export declare const readRuntimeTables: (input: CatalogInput) => Effect.Effect<ReadonlySet<string>, SqlError>;
|
|
57
64
|
export declare const migrate: (input: MigrateInput) => Effect.Effect<{
|
|
58
65
|
readonly plan: MigrationPlan;
|
|
59
66
|
readonly result: MigrationResult;
|
package/dist/migrate/apply.js
CHANGED
|
@@ -3,7 +3,7 @@ import { canonicalJson, decodeManifestDocument, encodeManifest, manifestHash, }
|
|
|
3
3
|
import { CatalogInvalid, CatalogMismatch, MigrationFailed, MigrationRefused } from "./errors.js";
|
|
4
4
|
import { isNoopMigration } from "./model.js";
|
|
5
5
|
import { planMigration } from "./plan.js";
|
|
6
|
-
import { CATALOG_TABLE, quoteIdentifier } from "./storage.js";
|
|
6
|
+
import { API_KEYS_TABLE, CATALOG_TABLE, OAUTH_TABLES, USER_ROLES_TABLE, quoteIdentifier, quoteLiteral, } from "./storage.js";
|
|
7
7
|
const CATALOG = quoteIdentifier(CATALOG_TABLE);
|
|
8
8
|
/** Serializes migrations of one database; transaction-scoped, so it ends with the transaction. */
|
|
9
9
|
const MIGRATION_LOCK = "segmentstream.ontology.migration";
|
|
@@ -133,11 +133,28 @@ export const applyMigration = (plan, options) => Effect.gen(function* () {
|
|
|
133
133
|
* workspace database first as a dry run, then on production: the plan is made against each database's
|
|
134
134
|
* own catalog.
|
|
135
135
|
*/
|
|
136
|
+
/** The runtime's tables, beside the catalog and the entity tables. */
|
|
137
|
+
export const RUNTIME_TABLES = [
|
|
138
|
+
USER_ROLES_TABLE,
|
|
139
|
+
API_KEYS_TABLE,
|
|
140
|
+
...OAUTH_TABLES,
|
|
141
|
+
];
|
|
142
|
+
/**
|
|
143
|
+
* The runtime tables the database has, for `planMigration`'s `existingTables`: a database that an
|
|
144
|
+
* earlier SDK migrated lacks the tables added since.
|
|
145
|
+
*/
|
|
146
|
+
export const readRuntimeTables = (input) => input.sql
|
|
147
|
+
.unsafe(`SELECT "tablename" AS "name" FROM "pg_catalog"."pg_tables" ` +
|
|
148
|
+
`WHERE "schemaname" = current_schema() ` +
|
|
149
|
+
`AND "tablename" IN (${RUNTIME_TABLES.map(quoteLiteral).join(", ")})`)
|
|
150
|
+
.pipe(Effect.map((rows) => new Set(rows.map((row) => row.name))));
|
|
136
151
|
export const migrate = (input) => Effect.gen(function* () {
|
|
137
152
|
const current = yield* readCatalog({ sql: input.sql });
|
|
153
|
+
const existingTables = yield* readRuntimeTables({ sql: input.sql });
|
|
138
154
|
const plan = planMigration({
|
|
139
155
|
current,
|
|
140
156
|
target: input.target,
|
|
157
|
+
existingTables,
|
|
141
158
|
...(input.options === undefined ? {} : { options: input.options }),
|
|
142
159
|
});
|
|
143
160
|
const result = yield* applyMigration(plan, input);
|
package/dist/migrate/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { applyMigration, migrate, readCatalog } from "./apply.js";
|
|
1
|
+
export { applyMigration, migrate, readCatalog, readRuntimeTables, RUNTIME_TABLES, } from "./apply.js";
|
|
2
2
|
export type { ApplyMigrationError, ApplyMigrationOptions, CatalogInput, MigrateInput, MigrationResult, } from "./apply.js";
|
|
3
3
|
export { CatalogInvalid, CatalogMismatch, MigrationFailed, MigrationRefused } from "./errors.js";
|
|
4
4
|
export { isNoopMigration, MIGRATION_REFUSAL_CODES, MIGRATION_STEP_CLASSIFICATIONS, MIGRATION_STEP_KINDS, MigrationPlan, MigrationRefusal, MigrationStep, } from "./model.js";
|
package/dist/migrate/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { applyMigration, migrate, readCatalog } from "./apply.js";
|
|
1
|
+
export { applyMigration, migrate, readCatalog, readRuntimeTables, RUNTIME_TABLES, } from "./apply.js";
|
|
2
2
|
export { CatalogInvalid, CatalogMismatch, MigrationFailed, MigrationRefused } from "./errors.js";
|
|
3
3
|
export { isNoopMigration, MIGRATION_REFUSAL_CODES, MIGRATION_STEP_CLASSIFICATIONS, MIGRATION_STEP_KINDS, MigrationPlan, MigrationRefusal, MigrationStep, } from "./model.js";
|
|
4
4
|
export { planMigration } from "./plan.js";
|
package/dist/migrate/model.d.ts
CHANGED
|
@@ -123,6 +123,10 @@ export declare const MigrationPlan: Schema.Struct<{
|
|
|
123
123
|
readonly permission: Schema.optionalKey<Schema.String>;
|
|
124
124
|
readonly input: Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>;
|
|
125
125
|
readonly connections: Schema.optionalKey<Schema.$Array<Schema.String>>;
|
|
126
|
+
readonly hints: Schema.optionalKey<Schema.Struct<{
|
|
127
|
+
readonly destructive: Schema.optionalKey<Schema.Boolean>;
|
|
128
|
+
readonly idempotent: Schema.optionalKey<Schema.Boolean>;
|
|
129
|
+
}>>;
|
|
126
130
|
}>>;
|
|
127
131
|
readonly permissions: Schema.optionalKey<Schema.Struct<{
|
|
128
132
|
readonly read: Schema.String;
|
|
@@ -230,6 +234,10 @@ export declare const MigrationPlan: Schema.Struct<{
|
|
|
230
234
|
readonly permission: Schema.optionalKey<Schema.String>;
|
|
231
235
|
readonly input: Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>;
|
|
232
236
|
readonly connections: Schema.optionalKey<Schema.$Array<Schema.String>>;
|
|
237
|
+
readonly hints: Schema.optionalKey<Schema.Struct<{
|
|
238
|
+
readonly destructive: Schema.optionalKey<Schema.Boolean>;
|
|
239
|
+
readonly idempotent: Schema.optionalKey<Schema.Boolean>;
|
|
240
|
+
}>>;
|
|
233
241
|
}>>;
|
|
234
242
|
readonly permissions: Schema.optionalKey<Schema.Struct<{
|
|
235
243
|
readonly read: Schema.String;
|
package/dist/migrate/plan.d.ts
CHANGED
|
@@ -12,6 +12,12 @@ export interface PlanMigrationInput {
|
|
|
12
12
|
readonly current: OntologyManifest | undefined;
|
|
13
13
|
readonly target: OntologyManifest;
|
|
14
14
|
readonly options?: MigrationOptions;
|
|
15
|
+
/**
|
|
16
|
+
* The runtime tables the database has, from `readRuntimeTables`. A database migrated by an earlier
|
|
17
|
+
* SDK lacks the tables added since, and the plan creates them. Without it, the plan assumes the
|
|
18
|
+
* database has every runtime table.
|
|
19
|
+
*/
|
|
20
|
+
readonly existingTables?: ReadonlySet<string>;
|
|
15
21
|
}
|
|
16
22
|
/**
|
|
17
23
|
* Plans the migration from the applied manifest to the target. It is pure: the same manifests always
|
package/dist/migrate/plan.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BLOB_TABLES_DDL } from "../storage/tables.js";
|
|
2
2
|
import { SNAKE_CASE_NAME, isSystemProperty, toSnakeCase } from "../names.js";
|
|
3
|
-
import { CATALOG_TABLE_DDL, MAX_IDENTIFIER_LENGTH, USER_TABLE, addConstraintStatement, columnDefinition, constraintDefinition, createEnumStatement, createIndexStatement, createTableStatement, defaultExpression, entityStorage, enumTypeName, fieldColumnName, joinTable, propertyCheck, blobForeignKey, propertyColumn, propertyEnum, quoteIdentifier, quoteLiteral, relationshipColumn, RUNTIME_TABLES_DDL, relationshipForeignKey, SYSTEM_COLUMNS, tableName, } from "./storage.js";
|
|
3
|
+
import { CATALOG_TABLE_DDL, MAX_IDENTIFIER_LENGTH, OAUTH_TABLES, OAUTH_TABLES_DDL, USER_TABLE, addConstraintStatement, columnDefinition, constraintDefinition, createEnumStatement, createIndexStatement, createTableStatement, defaultExpression, entityStorage, enumTypeName, fieldColumnName, joinTable, propertyCheck, blobForeignKey, propertyColumn, propertyEnum, quoteIdentifier, quoteLiteral, relationshipColumn, RUNTIME_TABLES_DDL, relationshipForeignKey, SYSTEM_COLUMNS, tableName, } from "./storage.js";
|
|
4
4
|
const GLOBAL_KINDS = new Set(["table", "type", "index"]);
|
|
5
5
|
function step(input) {
|
|
6
6
|
return {
|
|
@@ -69,10 +69,18 @@ export function planMigration(input) {
|
|
|
69
69
|
draft.runtimeTables.push(step({
|
|
70
70
|
kind: "createCatalog",
|
|
71
71
|
classification: "additive",
|
|
72
|
-
description: "Create the runtime's role assignment
|
|
72
|
+
description: "Create the runtime's role assignment, API key and OAuth tables.",
|
|
73
73
|
sql: RUNTIME_TABLES_DDL,
|
|
74
74
|
}));
|
|
75
75
|
}
|
|
76
|
+
else if (OAUTH_TABLES.some((table) => input.existingTables?.has(table) === false)) {
|
|
77
|
+
draft.runtimeTables.push(step({
|
|
78
|
+
kind: "createCatalog",
|
|
79
|
+
classification: "additive",
|
|
80
|
+
description: "Create the runtime's OAuth tables, which connect agents to the MCP server.",
|
|
81
|
+
sql: OAUTH_TABLES_DDL,
|
|
82
|
+
}));
|
|
83
|
+
}
|
|
76
84
|
if (storedTargets.some((entity) => entity.properties.some((property) => property.type === "blob")) &&
|
|
77
85
|
!current?.entities.some((entity) => entity.properties.some((property) => property.type === "blob"))) {
|
|
78
86
|
draft.runtimeTables.push(step({
|
|
@@ -151,6 +151,18 @@ export declare const USER_ROLES_TABLE = "_user_roles";
|
|
|
151
151
|
* secret only as a salted PBKDF2 hash.
|
|
152
152
|
*/
|
|
153
153
|
export declare const API_KEYS_TABLE = "_api_keys";
|
|
154
|
+
/** OAuth clients that registered themselves to connect agents to the MCP server. */
|
|
155
|
+
export declare const OAUTH_CLIENTS_TABLE = "_oauth_clients";
|
|
156
|
+
/** Authorization requests waiting for a member's consent, for a few minutes. */
|
|
157
|
+
export declare const OAUTH_REQUESTS_TABLE = "_oauth_requests";
|
|
158
|
+
/** What a member allowed a client to do: revoking a grant stops its tokens. */
|
|
159
|
+
export declare const OAUTH_GRANTS_TABLE = "_oauth_grants";
|
|
160
|
+
/** Authorization codes, access tokens and refresh tokens, stored only as SHA-256 hashes. */
|
|
161
|
+
export declare const OAUTH_TOKENS_TABLE = "_oauth_tokens";
|
|
162
|
+
/** The OAuth tables, in the order they are created. */
|
|
163
|
+
export declare const OAUTH_TABLES: ReadonlyArray<string>;
|
|
164
|
+
/** The OAuth tables of the MCP server's authorization server. Every statement is idempotent. */
|
|
165
|
+
export declare const OAUTH_TABLES_DDL: ReadonlyArray<string>;
|
|
154
166
|
/**
|
|
155
167
|
* The runtime's own tables beside the catalog. They are created with it, after the entity tables
|
|
156
168
|
* because they refer to the built-in user table, and every statement is idempotent.
|