@neon/tools 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # `@neon/tools`
2
2
 
3
- Generated agent tools for every operation in the Neon Management API. Select only the operations an agent needs, then use the canonical descriptors directly or adapt them for MCP, Eve, or Mastra.
3
+ Agent tools for the Neon Management API and for the `@neon/sdk` workflows that attach compute and return a connection string. Select only the operations and workflows an agent needs, then use the canonical descriptors directly or adapt them for MCP, Eve, and Mastra.
4
4
 
5
5
  ```bash
6
6
  npm install @neon/tools
@@ -24,7 +24,7 @@ const tools = createNeonTools({
24
24
  });
25
25
 
26
26
  const result = await tools.listProjects.execute({
27
- query: { limit: 10 },
27
+ limit: 10,
28
28
  });
29
29
  ```
30
30
 
@@ -43,14 +43,58 @@ Or supply the token per call:
43
43
  const tools = createNeonTools({ operations });
44
44
 
45
45
  await tools.listProjects.execute(
46
- { query: { limit: 10 } },
46
+ { limit: 10 },
47
47
  { apiKey: oauthAccessToken },
48
48
  );
49
49
  ```
50
50
 
51
- The returned record is keyed by OpenAPI operation ID. Each tool includes its generated Zod 4 `inputSchema`, snake-case `id`, title, description, safety annotations, stability metadata, and an `execute()` function. Inputs group API parameters under `path`, `query`, `headers`, and `body`.
51
+ The returned record is keyed by OpenAPI operation ID or workflow id. Each tool includes its Zod 4 `inputSchema`, snake-case `id`, title, description, safety annotations, stability metadata, and an `execute()` function. Inputs are flat: path, query, header, and body fields sit on one object. A body that is a single object wrapper is lifted, so `create_project` takes `{ name, region_id, org_id, ... }` rather than `{ project: { name } }`. A body with several properties keeps those properties, so `create_project_branch` takes `{ project_id, branch, endpoints, annotation_value }` and `branch` is still an object. Two email-provider updates keep a `body` field because the API request is a discriminated union.
52
52
 
53
- `operationIds` exports every valid selector. `execute()` strictly validates the input, rejects unknown fields instead of dropping them, and returns typed, JSON-safe `{ data }`. Neon SDK errors remain typed and are thrown to the caller.
53
+ `operationIds` exports every valid operation selector. `execute()` strictly validates the input, rejects unknown fields instead of dropping them, and returns typed, JSON-safe `{ data }`. Neon SDK errors remain typed and are thrown to the caller.
54
+
55
+ ## Workflows
56
+
57
+ `workflows` selects methods from the `@neon/sdk` ergonomic client. These are not OpenAPI operations: they attach a default compute, wait until the resource is ready, and return a connection string. `operations` is the generated Management API. At least one of the two arrays is required.
58
+
59
+ Both workflow tools poll until the resource is ready. The default deadline is five minutes (`wait.timeoutMs`). Pass `wait: { timeoutMs: 30_000 }` on `createNeonTools` or `createNeonTool` to bound that. Set it below the host's own tool-call timeout, otherwise the host gives up first. An abort `signal` on `execute` or a wait timeout stops the poll, not the create: the branch or project may already exist, and the error does not include its id. List before retrying. `metadata.method` and `metadata.path` name the first request; extra readiness GETs are not listed there. `inject.projectId` still works on `createBranchWithCompute` because its path is `/projects/{project_id}/branches`.
60
+
61
+ ```ts
62
+ const tools = createNeonTools({
63
+ apiKey,
64
+ operations: ["listProjects"],
65
+ workflows: ["createBranchWithCompute", "createProjectAndConnect"],
66
+ });
67
+
68
+ const { data } = await tools.createBranchWithCompute.execute({
69
+ project_id: "project-id",
70
+ name: "feature-x",
71
+ });
72
+
73
+ await tools.createProjectAndConnect.execute({
74
+ name: "agent-project",
75
+ region_id: "aws-us-east-1",
76
+ });
77
+ ```
78
+
79
+ `createNeonTool` accepts the same workflow ids:
80
+
81
+ ```ts
82
+ const createBranch = createNeonTool("createBranchWithCompute", { apiKey });
83
+ ```
84
+
85
+ `workflowIds` lists the selectors. Record keys name the entity (`createBranchWithCompute`, `createProjectAndConnect`) and call `neon.branches.createWithCompute` and `neon.projects.createAndConnect`. Published ids are `create_branch_with_compute` and `create_project_and_connect`. Input fields are snake_case, same as generated tools. `names` can rename a workflow the same way it renames an operation:
86
+
87
+ ```ts
88
+ const tools = createNeonTools({
89
+ apiKey,
90
+ workflows: ["createBranchWithCompute"],
91
+ names: { createBranchWithCompute: "create_branch" },
92
+ });
93
+
94
+ tools.createBranchWithCompute.id; // "create_branch"
95
+ ```
96
+
97
+ `create_project_branch` still creates a branch with no compute when `endpoints` is omitted. It can attach compute if you pass `endpoints`; it does not wait or return a connection string. Use `createBranchWithCompute` when the next step needs to connect.
54
98
 
55
99
  ## Optional host add-ons
56
100
 
@@ -96,9 +140,27 @@ const tools = createNeonTools({
96
140
 
97
141
  This package does not send analytics. Mutating `event.input` does not change a grant-locked project or branch id.
98
142
 
143
+ ### Names
144
+
145
+ `name` rewrites every published tool `id`. `names` overrides one tool first, keyed by OpenAPI operation ID or the generated snake-case `id`:
146
+
147
+ ```ts
148
+ const tools = createNeonTools({
149
+ apiKey,
150
+ operations: ["createProjectBranch", "listProjects"] as const,
151
+ names: { createProjectBranch: "create_branch" },
152
+ name: (id) => `neon_${id}`,
153
+ });
154
+
155
+ tools.createProjectBranch.id; // "neon_create_branch"
156
+ tools.listProjects.id; // "neon_list_projects"
157
+ ```
158
+
159
+ The record is still keyed by operation ID (`tools.createProjectBranch`). MCP and Mastra publish `tool.id`. Eve uses the filename as the model-facing name, so name the file after the published `id`. Duplicate or non-snake-case ids throw, and a `names` key that matches no selected tool throws.
160
+
99
161
  ### Project and branch injection
100
162
 
101
- Generated tools take OpenAPI path parameters (`path.project_id`, `path.branch_id`). A host that already knows those values can inject them. Without `omitFromSchema`, the published field becomes optional and a caller-supplied value wins. With `omitFromSchema: true`, the field is removed from the published schema and the injector is the only source:
163
+ Tools take path parameters as `project_id` and `branch_id`. A host that already knows those values can inject them, including on `createBranchWithCompute`. Without `omitFromSchema`, the published field becomes optional and a caller-supplied value wins. With `omitFromSchema: true`, the field is removed from the published schema and the injector is the only source:
102
164
 
103
165
  ```ts
104
166
  const tools = createNeonTools({
@@ -111,7 +173,7 @@ const tools = createNeonTools({
111
173
  });
112
174
 
113
175
  await tools.getProject.execute({});
114
- await tools.deleteProjectBranch.execute({ path: { branch_id: "br-id" } });
176
+ await tools.deleteProjectBranch.execute({ branch_id: "br-id" });
115
177
  ```
116
178
 
117
179
  Use a getter when the value is request-scoped. The getter can read the host's own `AsyncLocalStorage` (this package does not export one):
@@ -134,7 +196,9 @@ await grant.run({ projectId: "project-id" }, () => tools.getProject.execute({}))
134
196
 
135
197
  Injectors only apply to tools that have that path key. `listProjects` is unchanged. Empty inject values fail closed. Invalid ids still fail the original path schema before fetch.
136
198
 
137
- These add-ons do not flatten `{ path, query, body }` into camelCase `projectId`, do not rename tools (`get_project` is not `describe_project`), and do not add host-only behavior such as returning a connection string from `createProject`. Grant filtering, read-only filtering, and access-control notices stay in the host. `branchId` injection fills `path.branch_id` only — query/body branch selectors such as `getConnectionURI`'s `query.branch_id` are unchanged.
199
+ `onExecute` and `inject` apply to workflow tools the same way they apply to generated tools. Grant filtering, read-only filtering, and access-control notices stay in the host.
200
+
201
+ Injection reads the URL template, so it fills path `project_id` and `branch_id` only. Query and body fields with those names stay caller-supplied, including `getConnectionURI.branch_id`, `createOrgApiKey.project_id`, `createNeonAuthIntegration.project_id` / `branch_id`, `createNeonAuthNewUser.project_id`, `createNeonAuthProviderSDKKeys.project_id`, `transferNeonAuthProviderProject.project_id`, `addProjectJWKS.branch_id`, `createProjectEndpoint.branch_id`, `updateProjectEndpoint.branch_id`, and `getProjectAdvisorSecurityIssues.branch_id`. `omitFromSchema: true` does not hide those fields.
138
202
 
139
203
  ## Request schemas
140
204
 
@@ -152,6 +216,8 @@ const body = zCreateProjectBody.parse({
152
216
  });
153
217
  ```
154
218
 
219
+ These are the raw OpenAPI request shapes, not the flat tool input. `zCreateProjectBody` still wraps fields in `project`. The tool `create_project` does not.
220
+
155
221
  These schemas are strict. If a newly added API field is not recognized, upgrade `@neon/tools`; use `@neon/sdk` directly until a matching tools release is available.
156
222
 
157
223
  ## MCP
@@ -262,12 +328,10 @@ const deployFunction = createNeonTool(
262
328
  );
263
329
 
264
330
  await deployFunction.execute({
265
- path: {
266
- project_id: "project-id",
267
- branch_id: "branch-id",
268
- slug: "hello",
269
- },
270
- body: { zip: "UEsDBA==" },
331
+ project_id: "project-id",
332
+ branch_id: "branch-id",
333
+ slug: "hello",
334
+ zip: "UEsDBA==",
271
335
  });
272
336
  ```
273
337
 
package/dist/index.d.ts CHANGED
@@ -1,29 +1,89 @@
1
1
  import { type NeonConfig, NeonError } from "@neon/sdk";
2
2
  import { type NeonBearerCredential } from "./lib/auth.js";
3
- import { type InjectedNeonTool, type NeonToolCustomizeOptions, type NeonToolInjectOptions } from "./lib/customize.js";
3
+ import { type InjectedNeonTool, type NeonToolCustomizeOptions, type NeonToolInjectOptions, type NeonToolNameOverrides } from "./lib/customize.js";
4
+ import { type NeonWorkflowId, type WorkflowFactories, workflowIds } from "./lib/workflows.js";
4
5
  import { type NeonOperationId, operationFactories, operationIds } from "./operations.gen.js";
5
6
  export type { NeonBearerCredential } from "./lib/auth.js";
6
- export type { InjectedNeonTool, NeonToolCustomizeOptions, NeonToolDescriptionOverrides, NeonToolDescriptionSource, NeonToolInjectOptions, NeonToolInjectValue, NeonToolOnExecute, NeonToolOnExecuteEvent, } from "./lib/customize.js";
7
+ export type { InjectedNeonTool, NeonToolCustomizeOptions, NeonToolDescriptionOverrides, NeonToolDescriptionSource, NeonToolInjectOptions, NeonToolInjectValue, NeonToolNameOverrides, NeonToolNameSource, NeonToolOnExecute, NeonToolOnExecuteEvent, } from "./lib/customize.js";
7
8
  export type { JsonSafe, JsonSafeBlob, NeonTool, NeonToolAnnotations, NeonToolExecutionContext, NeonToolMetadata, NeonToolResult, } from "./lib/operation.js";
8
- export type { NeonOperationId };
9
- export { NeonError, operationIds };
9
+ export type { NeonOperationId, NeonWorkflowId };
10
+ export { NeonError, operationIds, workflowIds };
10
11
  type OperationFactories = typeof operationFactories;
11
- export type NeonTools<Operations extends readonly NeonOperationId[]> = {
12
+ export type NeonTools<Operations extends readonly NeonOperationId[] = [], Workflows extends readonly NeonWorkflowId[] = []> = {
12
13
  [Operation in Operations[number]]: ReturnType<OperationFactories[Operation]>;
14
+ } & {
15
+ [Workflow in Workflows[number]]: ReturnType<WorkflowFactories[Workflow]>;
13
16
  };
14
- export type InjectedNeonTools<Operations extends readonly NeonOperationId[], Inject> = {
17
+ export type InjectedNeonTools<Operations extends readonly NeonOperationId[], Inject, Workflows extends readonly NeonWorkflowId[] = []> = {
15
18
  [Operation in Operations[number]]: InjectedNeonTool<ReturnType<OperationFactories[Operation]>, Inject>;
19
+ } & {
20
+ [Workflow in Workflows[number]]: InjectedNeonTool<ReturnType<WorkflowFactories[Workflow]>, Inject>;
16
21
  };
17
- export interface NeonToolsClientOptions extends Pick<NeonConfig, "baseUrl" | "fetch">, NeonToolCustomizeOptions {
22
+ type WithPublishedId<Tool> = Tool extends {
23
+ id: string;
24
+ } ? Omit<Tool, "id"> & {
25
+ id: string;
26
+ } : Tool;
27
+ export interface NeonToolsClientOptions extends Pick<NeonConfig, "baseUrl" | "fetch" | "wait">, Omit<NeonToolCustomizeOptions, "name" | "names"> {
18
28
  apiKey?: NeonBearerCredential;
19
29
  }
20
- export interface CreateNeonToolsOptions<Operations extends readonly NeonOperationId[]> extends NeonToolsClientOptions {
21
- operations: Operations;
30
+ interface OperationSelection {
31
+ operations: readonly NeonOperationId[];
32
+ workflows?: readonly NeonWorkflowId[];
33
+ }
34
+ interface WorkflowSelection {
35
+ workflows: readonly NeonWorkflowId[];
36
+ operations?: readonly NeonOperationId[];
22
37
  }
23
- export declare const createNeonTools: <const Operations extends readonly NeonOperationId[], const Inject extends NeonToolInjectOptions | undefined = undefined>(options: CreateNeonToolsOptions<Operations> & {
38
+ type CreateNeonToolsInput = NeonToolsClientOptions & (OperationSelection | WorkflowSelection);
39
+ export type CreateNeonToolsOptions<Operations extends readonly NeonOperationId[] = readonly NeonOperationId[], Workflows extends readonly NeonWorkflowId[] = readonly []> = NeonToolsClientOptions & (Workflows extends readonly [] ? {
40
+ operations: Operations;
41
+ workflows?: Workflows;
42
+ } : Operations extends readonly [] ? {
43
+ workflows: Workflows;
44
+ operations?: Operations;
45
+ } : {
46
+ operations: Operations;
47
+ workflows: Workflows;
48
+ });
49
+ type SelectedOperations<T> = T extends {
50
+ operations: infer O extends readonly NeonOperationId[];
51
+ } ? O : [];
52
+ type SelectedWorkflows<T> = T extends {
53
+ workflows: infer W extends readonly NeonWorkflowId[];
54
+ } ? W : [];
55
+ type NeonToolsFor<T, Inject> = T extends CreateNeonToolsInput ? Inject extends NeonToolInjectOptions ? InjectedNeonTools<SelectedOperations<T>, Inject, SelectedWorkflows<T>> : NeonTools<SelectedOperations<T>, SelectedWorkflows<T>> : never;
56
+ type NeonToolId = NeonOperationId | NeonWorkflowId;
57
+ type ToolForId<Id extends NeonToolId> = Id extends NeonWorkflowId ? ReturnType<WorkflowFactories[Id]> : Id extends NeonOperationId ? ReturnType<OperationFactories[Id]> : never;
58
+ type NamedNeonTools<Operations extends readonly NeonOperationId[], Workflows extends readonly NeonWorkflowId[], Inject> = {
59
+ [Operation in Operations[number]]: WithPublishedId<Inject extends NeonToolInjectOptions ? InjectedNeonTool<ReturnType<OperationFactories[Operation]>, Inject> : ReturnType<OperationFactories[Operation]>>;
60
+ } & {
61
+ [Workflow in Workflows[number]]: WithPublishedId<Inject extends NeonToolInjectOptions ? InjectedNeonTool<ReturnType<WorkflowFactories[Workflow]>, Inject> : ReturnType<WorkflowFactories[Workflow]>>;
62
+ };
63
+ type NamedNeonTool<Id extends NeonToolId, Inject> = WithPublishedId<Inject extends NeonToolInjectOptions ? InjectedNeonTool<ToolForId<Id>, Inject> : ToolForId<Id>>;
64
+ type NamedNeonToolsFor<T, Inject> = T extends CreateNeonToolsInput ? NamedNeonTools<SelectedOperations<T>, SelectedWorkflows<T>, Inject> : never;
65
+ export declare function createNeonTools<const T extends CreateNeonToolsInput, const Inject extends NeonToolInjectOptions | undefined = undefined>(options: T & {
66
+ inject?: Inject;
67
+ } & ({
68
+ name: (id: string) => string;
69
+ names?: NeonToolNameOverrides;
70
+ } | {
71
+ names: NeonToolNameOverrides;
72
+ name?: (id: string) => string;
73
+ })): NamedNeonToolsFor<T, Inject>;
74
+ export declare function createNeonTools<const T extends CreateNeonToolsInput, const Inject extends NeonToolInjectOptions | undefined = undefined>(options: T & {
75
+ inject?: Inject;
76
+ }): NeonToolsFor<T, Inject>;
77
+ export declare function createNeonTool<const Id extends NeonToolId, const Inject extends NeonToolInjectOptions | undefined = undefined>(id: Id, options: NeonToolsClientOptions & {
24
78
  inject?: Inject;
25
- }) => Inject extends NeonToolInjectOptions ? InjectedNeonTools<Operations, Inject> : NeonTools<Operations>;
26
- export declare function createNeonTool<const Operation extends NeonOperationId, const Inject extends NeonToolInjectOptions | undefined = undefined>(operationId: Operation, options: NeonToolsClientOptions & {
79
+ } & ({
80
+ name: (id: string) => string;
81
+ names?: NeonToolNameOverrides;
82
+ } | {
83
+ names: NeonToolNameOverrides;
84
+ name?: (id: string) => string;
85
+ })): NamedNeonTool<Id, Inject>;
86
+ export declare function createNeonTool<const Id extends NeonToolId, const Inject extends NeonToolInjectOptions | undefined = undefined>(id: Id, options: NeonToolsClientOptions & {
27
87
  inject?: Inject;
28
- }): Inject extends NeonToolInjectOptions ? InjectedNeonTool<ReturnType<OperationFactories[Operation]>, Inject> : ReturnType<OperationFactories[Operation]>;
88
+ }): Inject extends NeonToolInjectOptions ? InjectedNeonTool<ToolForId<Id>, Inject> : ToolForId<Id>;
29
89
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,UAAU,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACzE,OAAO,EAEN,KAAK,oBAAoB,EAEzB,MAAM,eAAe,CAAC;AACvB,OAAO,EAIN,KAAK,gBAAgB,EACrB,KAAK,wBAAwB,EAC7B,KAAK,qBAAqB,EAC1B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACN,KAAK,eAAe,EACpB,kBAAkB,EAClB,YAAY,EACZ,MAAM,qBAAqB,CAAC;AAE7B,YAAY,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAC1D,YAAY,EACX,gBAAgB,EAChB,wBAAwB,EACxB,4BAA4B,EAC5B,yBAAyB,EACzB,qBAAqB,EACrB,mBAAmB,EACnB,iBAAiB,EACjB,sBAAsB,GACtB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACX,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,mBAAmB,EACnB,wBAAwB,EACxB,gBAAgB,EAChB,cAAc,GACd,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,eAAe,EAAE,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;AAEnC,KAAK,kBAAkB,GAAG,OAAO,kBAAkB,CAAC;AAEpD,MAAM,MAAM,SAAS,CAAC,UAAU,SAAS,SAAS,eAAe,EAAE,IAAI;KACrE,SAAS,IAAI,UAAU,CAAC,MAAM,CAAC,GAAG,UAAU,CAC5C,kBAAkB,CAAC,SAAS,CAAC,CAC7B;CACD,CAAC;AAEF,MAAM,MAAM,iBAAiB,CAC5B,UAAU,SAAS,SAAS,eAAe,EAAE,EAC7C,MAAM,IACH;KACF,SAAS,IAAI,UAAU,CAAC,MAAM,CAAC,GAAG,gBAAgB,CAClD,UAAU,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,EACzC,MAAM,CACN;CACD,CAAC;AAEF,MAAM,WAAW,sBAChB,SAAQ,IAAI,CAAC,UAAU,EAAE,SAAS,GAAG,OAAO,CAAC,EAC5C,wBAAwB;IACzB,MAAM,CAAC,EAAE,oBAAoB,CAAC;CAC9B;AAED,MAAM,WAAW,sBAAsB,CACtC,UAAU,SAAS,SAAS,eAAe,EAAE,CAC5C,SAAQ,sBAAsB;IAC/B,UAAU,EAAE,UAAU,CAAC;CACvB;AAiED,eAAO,MAAM,eAAe,GAC3B,KAAK,CAAC,UAAU,SAAS,SAAS,eAAe,EAAE,EACnD,KAAK,CAAC,MAAM,SAAS,qBAAqB,GAAG,SAAS,GAAG,SAAS,EAElE,SAAS,sBAAsB,CAAC,UAAU,CAAC,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,KAC/D,MAAM,SAAS,qBAAqB,GACpC,iBAAiB,CAAC,UAAU,EAAE,MAAM,CAAC,GACrC,SAAS,CAAC,UAAU,CAGE,CAAC;AAE1B,wBAAgB,cAAc,CAC7B,KAAK,CAAC,SAAS,SAAS,eAAe,EACvC,KAAK,CAAC,MAAM,SAAS,qBAAqB,GAAG,SAAS,GAAG,SAAS,EAElE,WAAW,EAAE,SAAS,EACtB,OAAO,EAAE,sBAAsB,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACnD,MAAM,SAAS,qBAAqB,GACpC,gBAAgB,CAAC,UAAU,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,GACnE,UAAU,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAS3C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,44 +1,77 @@
1
1
  import { missingBearerCredential, requireBearerCredential } from "./lib/auth.js";
2
2
  import { applyToolCustomization, assertToolCustomizeOptions, hasToolCustomization } from "./lib/customize.js";
3
+ import { isNeonWorkflowId, workflowFactoryFor, workflowIds } from "./lib/workflows.js";
3
4
  import { operationFactories, operationIds } from "./operations.gen.js";
4
5
  import { NeonError, createNeonClient } from "@neon/sdk";
5
6
  //#region src/index.ts
6
7
  const createRawClient = (options) => createNeonClient({
7
8
  apiKey: options.apiKey === void 0 ? missingBearerCredential : requireBearerCredential(options.apiKey),
8
9
  ...options.baseUrl === void 0 ? {} : { baseUrl: options.baseUrl },
9
- ...options.fetch === void 0 ? {} : { fetch: options.fetch }
10
+ ...options.fetch === void 0 ? {} : { fetch: options.fetch },
11
+ ...options.wait === void 0 ? {} : { wait: options.wait }
10
12
  }).client;
11
13
  const operationFactoryFor = (operationId) => {
12
14
  const knownOperationId = operationIds.find((candidate) => candidate === operationId);
13
15
  if (knownOperationId === void 0) throw new TypeError(`Unknown Neon operation "${operationId}".`);
14
16
  return operationFactories[knownOperationId];
15
17
  };
16
- function assertNeonTools(value, operations) {
18
+ const assertKnownNameKeys = (names, tools) => {
19
+ if (names === void 0 || typeof names === "function") return;
20
+ const known = new Set(tools.flatMap((tool) => [tool.operationId, tool.id]));
21
+ const unknown = Object.keys(names).filter((key) => !known.has(key));
22
+ if (unknown.length > 0) throw new TypeError(`Unknown Neon tool name override: ${unknown.join(", ")}`);
23
+ };
24
+ function assertNeonTools(value, operations, workflows) {
17
25
  if (typeof value !== "object" || value === null) throw new TypeError("Expected generated Neon tools to be an object.");
18
26
  for (const operationId of operations) if (!(operationId in value)) throw new TypeError(`Missing generated Neon tool "${operationId}".`);
27
+ for (const workflowId of workflows) if (!(workflowId in value)) throw new TypeError(`Missing Neon workflow tool "${workflowId}".`);
19
28
  }
20
29
  const bindTools = (options) => {
21
30
  assertToolCustomizeOptions(options);
22
- const selected = /* @__PURE__ */ new Set();
23
- const selectedFactories = options.operations.map((operationId) => {
24
- if (selected.has(operationId)) throw new Error(`Duplicate Neon operation "${operationId}"`);
25
- selected.add(operationId);
26
- return [operationId, operationFactoryFor(operationId)];
31
+ const operations = options.operations ?? [];
32
+ const workflows = options.workflows ?? [];
33
+ if (operations.length === 0 && workflows.length === 0) throw new TypeError("createNeonTools requires at least one operation or workflow");
34
+ const selectedOperations = /* @__PURE__ */ new Set();
35
+ const operationEntries = operations.map((operationId) => {
36
+ if (selectedOperations.has(operationId)) throw new Error(`Duplicate Neon operation "${operationId}"`);
37
+ selectedOperations.add(operationId);
38
+ return [operationId, operationFactoryFor(operationId)(createRawClient(options))];
39
+ });
40
+ const selectedWorkflows = /* @__PURE__ */ new Set();
41
+ const workflowEntries = workflows.map((workflowId) => {
42
+ if (selectedWorkflows.has(workflowId)) throw new Error(`Duplicate Neon workflow "${workflowId}"`);
43
+ selectedWorkflows.add(workflowId);
44
+ return [workflowId, workflowFactoryFor(workflowId)(options)];
27
45
  });
28
- const client = createRawClient(options);
29
- const entries = selectedFactories.map(([operationId, factory]) => {
30
- const tool = factory(client);
31
- return [operationId, hasToolCustomization(options) ? applyToolCustomization(tool, options) : tool];
46
+ const rawEntries = [...operationEntries, ...workflowEntries];
47
+ assertKnownNameKeys(options.names, rawEntries.map(([, tool]) => tool));
48
+ const entries = rawEntries.map(([id, tool]) => {
49
+ return [id, hasToolCustomization(options) ? applyToolCustomization(tool, options) : tool];
32
50
  });
51
+ const publishedIds = /* @__PURE__ */ new Map();
52
+ for (const [id, tool] of entries) {
53
+ const previous = publishedIds.get(tool.id);
54
+ if (previous !== void 0) throw new Error(`Duplicate Neon tool id "${tool.id}" for ${previous}, ${id}`);
55
+ publishedIds.set(tool.id, id);
56
+ }
33
57
  const tools = Object.fromEntries(entries);
34
- assertNeonTools(tools, options.operations);
58
+ assertNeonTools(tools, operations, workflows);
35
59
  return tools;
36
60
  };
37
- const createNeonTools = (options) => bindTools(options);
38
- function createNeonTool(operationId, options) {
61
+ function createNeonTools(options) {
62
+ return bindTools(options);
63
+ }
64
+ function createNeonTool(id, options) {
39
65
  assertToolCustomizeOptions(options);
40
- const tool = operationFactoryFor(operationId)(createRawClient(options));
66
+ let tool;
67
+ if (isNeonWorkflowId(id)) tool = workflowFactoryFor(id)(options);
68
+ else {
69
+ const knownOperationId = operationIds.find((candidate) => candidate === id);
70
+ if (knownOperationId === void 0) throw new TypeError(`Unknown Neon operation or workflow "${id}".`);
71
+ tool = operationFactories[knownOperationId](createRawClient(options));
72
+ }
73
+ assertKnownNameKeys(options.names, [tool]);
41
74
  return hasToolCustomization(options) ? applyToolCustomization(tool, options) : tool;
42
75
  }
43
76
  //#endregion
44
- export { NeonError, createNeonTool, createNeonTools, operationIds };
77
+ export { NeonError, createNeonTool, createNeonTools, operationIds, workflowIds };
@@ -13,6 +13,8 @@ export interface NeonToolDescriptionSource {
13
13
  description: string;
14
14
  }
15
15
  export type NeonToolDescriptionOverrides = Readonly<Record<string, string>> | ((tool: NeonToolDescriptionSource) => string);
16
+ export type NeonToolNameSource = Pick<NeonToolDescriptionSource, "operationId" | "id">;
17
+ export type NeonToolNameOverrides = Readonly<Record<string, string>> | ((tool: NeonToolNameSource) => string);
16
18
  export interface NeonToolOnExecuteEvent<Output = unknown> {
17
19
  operationId: string;
18
20
  id: string;
@@ -22,31 +24,29 @@ export interface NeonToolOnExecuteEvent<Output = unknown> {
22
24
  export type NeonToolOnExecute = <Output>(event: NeonToolOnExecuteEvent<Output>) => Promise<NeonToolResult<Output>>;
23
25
  export interface NeonToolCustomizeOptions {
24
26
  descriptions?: NeonToolDescriptionOverrides;
27
+ names?: NeonToolNameOverrides;
28
+ name?: (id: string) => string;
25
29
  onExecute?: NeonToolOnExecute;
26
30
  inject?: NeonToolInjectOptions;
27
31
  }
28
32
  type InjectedPathKey<Inject> = ("projectId" extends keyof Inject ? Inject["projectId"] extends undefined ? never : "project_id" : never) | ("branchId" extends keyof Inject ? Inject["branchId"] extends undefined ? never : "branch_id" : never);
29
- type OptionalInjectedPath<Path, Keys extends string> = [
30
- keyof Omit<Path, Keys>
31
- ] extends [never] ? {
32
- path?: Omit<Path, Keys> & Partial<Pick<Path, Extract<Keys, keyof Path>>>;
33
- } : {
34
- path: Omit<Path, Keys> & Partial<Pick<Path, Extract<Keys, keyof Path>>>;
35
- };
36
- type ApplyInjectToInput<Input, Inject> = [InjectedPathKey<Inject>] extends [
37
- never
38
- ] ? Input : Input extends {
39
- path: infer Path;
40
- } ? Inject extends {
33
+ type RequiredKeys<Input> = {
34
+ [Key in keyof Input]-?: object extends Pick<Input, Key> ? never : Key;
35
+ }[keyof Input];
36
+ type InjectedRequiredKey<Input, Inject> = Extract<InjectedPathKey<Inject>, RequiredKeys<Input>>;
37
+ type ApplyInjectToInput<Input, Inject> = [
38
+ InjectedRequiredKey<Input, Inject>
39
+ ] extends [never] ? Input : Inject extends {
41
40
  omitFromSchema: true;
42
- } ? [keyof Omit<Path, InjectedPathKey<Inject>>] extends [never] ? Omit<Input, "path"> : Omit<Input, "path"> & {
43
- path: Omit<Path, InjectedPathKey<Inject>>;
44
- } : Omit<Input, "path"> & OptionalInjectedPath<Path, InjectedPathKey<Inject>> : Input;
41
+ } ? Omit<Input, InjectedRequiredKey<Input, Inject>> : Omit<Input, InjectedRequiredKey<Input, Inject>> & Partial<Pick<Input, Extract<InjectedRequiredKey<Input, Inject>, keyof Input>>>;
45
42
  export type InjectedNeonTool<Tool, Inject> = Tool extends NeonTool<infer Schema, string, infer Output> ? Omit<Tool, "execute"> & {
46
43
  execute(input: ApplyInjectToInput<z.input<Schema>, Inject>, context?: NeonToolExecutionContext): Promise<NeonToolResult<Output>>;
47
44
  } : Tool;
45
+ export declare const pathTemplateParams: (path: string) => Set<string>;
48
46
  export declare const assertToolCustomizeOptions: (options: NeonToolCustomizeOptions) => void;
49
47
  export declare const hasToolCustomization: (options: NeonToolCustomizeOptions) => boolean;
50
- export declare const applyToolCustomization: <Tool extends NeonTool>(tool: Tool, options: NeonToolCustomizeOptions) => Tool;
48
+ export declare const applyToolCustomization: <Tool extends NeonTool>(tool: Tool, options: NeonToolCustomizeOptions) => Omit<Tool, "id"> & {
49
+ id: string;
50
+ };
51
51
  export {};
52
52
  //# sourceMappingURL=customize.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"customize.d.ts","sourceRoot":"","sources":["../../src/lib/customize.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"customize.d.ts","sourceRoot":"","sources":["../../src/lib/customize.ts"],"names":[],"mappings":"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"}
@@ -1,24 +1,51 @@
1
1
  import * as z from "zod";
2
2
  //#region src/lib/customize.ts
3
+ const PATH_INJECT = [["projectId", "project_id"], ["branchId", "branch_id"]];
4
+ const PUBLISHED_ID = /^[a-z][a-z0-9_]*$/;
3
5
  const missingInjectMessage = (name) => `A ${name} inject value is required`;
4
6
  const isPlainObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
7
+ const pathTemplateParams = (path) => new Set([...path.matchAll(/\{([^{}]+)\}/g)].map((match) => match[1]));
5
8
  const assertToolCustomizeOptions = (options) => {
6
9
  resolveInject(options.inject);
10
+ if (options.name !== void 0 && typeof options.name !== "function") throw new TypeError("Neon tool name transforms must be functions");
11
+ if (options.names !== void 0 && typeof options.names !== "function" && (typeof options.names !== "object" || options.names === null || Array.isArray(options.names))) throw new TypeError("Neon tool name overrides must be a map or a function");
7
12
  };
8
- const hasToolCustomization = (options) => options.descriptions !== void 0 || options.onExecute !== void 0 || resolveInject(options.inject).hasAny;
13
+ const hasToolCustomization = (options) => options.descriptions !== void 0 || options.names !== void 0 || options.name !== void 0 || options.onExecute !== void 0 || resolveInject(options.inject).hasAny;
9
14
  const applyToolCustomization = (tool, options) => {
10
15
  const inject = resolveInject(options.inject);
16
+ const id = publishedId(tool, options);
11
17
  const description = applyDescription(tool, options.descriptions);
12
- const inputSchema = publishInputSchema(tool.inputSchema, inject);
18
+ const inputSchema = publishInputSchema(tool.inputSchema, inject, pathTemplateParams(tool.metadata.path));
13
19
  const wrapExecute = options.onExecute !== void 0 || inject.hasAny;
14
- if (description === tool.description && inputSchema === tool.inputSchema && !wrapExecute) return tool;
15
20
  return {
16
21
  ...tool,
22
+ id,
17
23
  description,
18
24
  inputSchema,
19
- execute: wrapExecute ? wrapToolExecute(tool, options.onExecute, inject) : tool.execute
25
+ execute: wrapExecute ? wrapToolExecute({
26
+ ...tool,
27
+ id
28
+ }, options.onExecute, inject) : tool.execute
20
29
  };
21
30
  };
31
+ function publishedId(tool, options) {
32
+ let id = tool.id;
33
+ if (options.names !== void 0) {
34
+ if (typeof options.names === "function") {
35
+ id = options.names({
36
+ operationId: tool.operationId,
37
+ id: tool.id
38
+ });
39
+ if (typeof id !== "string") throw new TypeError(`Neon tool name overrides must return a string for ${tool.operationId}`);
40
+ } else {
41
+ const override = options.names[tool.operationId] ?? options.names[tool.id];
42
+ if (override !== void 0) id = override;
43
+ }
44
+ }
45
+ if (options.name !== void 0) id = options.name(id);
46
+ if (typeof id !== "string" || !PUBLISHED_ID.test(id)) throw new TypeError(`Neon tool id must match ${PUBLISHED_ID} for ${tool.operationId}: received ${JSON.stringify(id)}`);
47
+ return id;
48
+ }
22
49
  function resolveInject(inject) {
23
50
  if (inject === void 0) return {
24
51
  omitFromSchema: false,
@@ -64,10 +91,10 @@ function applyDescription(tool, descriptions) {
64
91
  }
65
92
  function wrapToolExecute(tool, onExecute, inject) {
66
93
  const originalExecute = tool.execute.bind(tool);
67
- const availableKeys = pathKeys(tool.inputSchema);
94
+ const availableKeys = pathTemplateParams(tool.metadata.path);
68
95
  const mode = inject.omitFromSchema ? "override" : "fill";
69
96
  return async (input, context) => {
70
- const run = async () => originalExecute(mergePathPatch(input, await resolveInjectedPath(input, inject, availableKeys, mode), mode), context);
97
+ const run = async () => originalExecute(mergeFields(input, await resolveInjectedFields(input, inject, availableKeys, mode), mode), context);
71
98
  if (onExecute === void 0) return run();
72
99
  return onExecute({
73
100
  operationId: tool.operationId,
@@ -77,10 +104,10 @@ function wrapToolExecute(tool, onExecute, inject) {
77
104
  });
78
105
  };
79
106
  }
80
- async function resolveInjectedPath(input, inject, availableKeys, mode) {
81
- const present = isPlainObject(input) && isPlainObject(input.path) ? input.path : void 0;
107
+ async function resolveInjectedFields(input, inject, availableKeys, mode) {
108
+ const present = isPlainObject(input) ? input : void 0;
82
109
  const patch = {};
83
- for (const [name, pathKey] of [["projectId", "project_id"], ["branchId", "branch_id"]]) {
110
+ for (const [name, pathKey] of PATH_INJECT) {
84
111
  if (!availableKeys.has(pathKey)) continue;
85
112
  const injector = inject[name];
86
113
  if (injector === void 0) continue;
@@ -95,78 +122,37 @@ async function resolveInjectedPath(input, inject, availableKeys, mode) {
95
122
  }
96
123
  return patch;
97
124
  }
98
- function mergePathPatch(input, patch, mode) {
125
+ function mergeFields(input, patch, mode) {
99
126
  if (Object.keys(patch).length === 0) return input === void 0 ? {} : input;
100
- if (input === void 0) return { path: patch };
127
+ if (input === void 0) return patch;
101
128
  if (!isPlainObject(input)) return input;
102
- const path = input.path;
103
- if (path === void 0) return {
104
- ...input,
105
- path: patch
106
- };
107
- if (!isPlainObject(path)) return input;
108
- const nextPath = { ...path };
109
- for (const [key, value] of Object.entries(patch)) if (mode === "override" || nextPath[key] === void 0) nextPath[key] = value;
110
- return {
111
- ...input,
112
- path: nextPath
113
- };
129
+ const next = { ...input };
130
+ for (const [key, value] of Object.entries(patch)) if (mode === "override" || next[key] === void 0) next[key] = value;
131
+ return next;
114
132
  }
115
133
  function cloneInput(input) {
116
134
  if (!isPlainObject(input)) return input;
117
- if (!isPlainObject(input.path)) return { ...input };
118
- return {
119
- ...input,
120
- path: { ...input.path }
121
- };
135
+ return { ...input };
122
136
  }
123
137
  function objectShape(schema) {
124
138
  if (schema instanceof z.ZodOptional) return objectShape(schema.unwrap());
125
139
  if (schema instanceof z.ZodObject) return schema.shape;
126
140
  }
127
- function pathKeys(schema) {
128
- const shape = objectShape(schema);
129
- if (shape?.path === void 0) return /* @__PURE__ */ new Set();
130
- const pathShape = objectShape(shape.path);
131
- if (pathShape === void 0) return /* @__PURE__ */ new Set();
132
- return new Set(Object.keys(pathShape));
133
- }
134
- function publishInputSchema(schema, inject) {
141
+ function publishInputSchema(schema, inject, pathKeys) {
135
142
  if (!inject.hasAny) return schema;
136
- const available = pathKeys(schema);
137
- const modes = {};
138
- if (inject.projectId !== void 0 && available.has("project_id")) modes.project_id = inject.omitFromSchema ? "omit" : "optional";
139
- if (inject.branchId !== void 0 && available.has("branch_id")) modes.branch_id = inject.omitFromSchema ? "omit" : "optional";
140
- if (modes.project_id === void 0 && modes.branch_id === void 0) return schema;
141
- return rewritePathSchema(schema, modes);
142
- }
143
- function rewritePathSchema(schema, modes) {
144
- if (!(schema instanceof z.ZodObject)) return schema;
145
- const shape = schema.shape;
146
- if (shape.path === void 0) return schema;
147
- let pathSchema = shape.path;
148
- if (shape.path instanceof z.ZodOptional) pathSchema = shape.path.unwrap();
149
- const pathWasOptional = shape.path instanceof z.ZodOptional;
150
- if (!(pathSchema instanceof z.ZodObject)) return schema;
151
- const pathShape = { ...pathSchema.shape };
143
+ const shape = objectShape(schema);
144
+ if (shape === void 0) return schema;
145
+ const nextShape = { ...shape };
152
146
  let changed = false;
153
- for (const key of ["project_id", "branch_id"]) {
154
- const mode = modes[key];
155
- if (mode === void 0 || pathShape[key] === void 0) continue;
147
+ for (const [name, pathKey] of PATH_INJECT) {
148
+ if (inject[name] === void 0 || !pathKeys.has(pathKey)) continue;
149
+ if (nextShape[pathKey] === void 0) continue;
156
150
  changed = true;
157
- if (mode === "omit") delete pathShape[key];
158
- else pathShape[key] = pathShape[key].optional();
151
+ if (inject.omitFromSchema) delete nextShape[pathKey];
152
+ else nextShape[pathKey] = nextShape[pathKey].optional();
159
153
  }
160
154
  if (!changed) return schema;
161
- const restShape = { ...shape };
162
- const remaining = Object.keys(pathShape);
163
- if (remaining.length === 0) {
164
- delete restShape.path;
165
- return Object.keys(restShape).length === 0 ? z.strictObject({}) : z.strictObject(restShape);
166
- }
167
- const nextPath = z.strictObject(pathShape);
168
- restShape.path = pathWasOptional || remaining.every((key) => pathShape[key] instanceof z.ZodOptional) ? nextPath.optional() : nextPath;
169
- return z.strictObject(restShape);
155
+ return Object.keys(nextShape).length === 0 ? z.strictObject({}) : z.strictObject(nextShape);
170
156
  }
171
157
  //#endregion
172
- export { applyToolCustomization, assertToolCustomizeOptions, hasToolCustomization };
158
+ export { applyToolCustomization, assertToolCustomizeOptions, hasToolCustomization, pathTemplateParams };