@protobase/server 0.42.0 → 0.43.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.
Files changed (50) hide show
  1. package/dist/aggregate-groups.js +1 -1
  2. package/dist/aggregate-service.js +3 -3
  3. package/dist/aggregate-splits.js +1 -1
  4. package/dist/ai/generate-route.js +1 -1
  5. package/dist/assistant/batch-approval.js +55 -0
  6. package/dist/assistant/batch-write-args.js +63 -0
  7. package/dist/assistant/batch-write-tool.d.ts +7 -0
  8. package/dist/assistant/batch-write-tool.js +115 -0
  9. package/dist/assistant/record-tool-args.js +14 -1
  10. package/dist/assistant/record-tools.js +16 -8
  11. package/dist/assistant/records.d.ts +11 -1
  12. package/dist/assistant/records.js +8 -5
  13. package/dist/batch/reorder.js +1 -1
  14. package/dist/batch/run-batch.d.ts +26 -0
  15. package/dist/batch/run-batch.js +2 -2
  16. package/dist/batch/schema.d.ts +221 -0
  17. package/dist/comments/mentionable.js +1 -1
  18. package/dist/comments/read-comments.js +1 -1
  19. package/dist/create-admin.js +1 -1
  20. package/dist/error-handler.js +1 -1
  21. package/dist/files/download.js +4 -4
  22. package/dist/files/present.js +1 -1
  23. package/dist/functions/records.d.ts +1 -1
  24. package/dist/functions/records.js +5 -2
  25. package/dist/history/read-history.js +3 -3
  26. package/dist/index.d.ts +5 -2
  27. package/dist/index.js +3 -2
  28. package/dist/jobs/run-job.d.ts +1 -1
  29. package/dist/list-photos.js +2 -2
  30. package/dist/list-service.js +3 -3
  31. package/dist/map-service.js +1 -1
  32. package/dist/mcp/mcp-tools.d.ts +3 -6
  33. package/dist/mcp/mcp-tools.js +3 -1
  34. package/dist/package.js +1 -1
  35. package/dist/read-service.js +7 -4
  36. package/dist/realtime/change-checker.js +1 -1
  37. package/dist/records.d.ts +5 -0
  38. package/dist/rest/rest-context.js +1 -1
  39. package/dist/reveal-service.js +1 -1
  40. package/dist/routes/batch.js +1 -1
  41. package/dist/routes/collection.js +1 -1
  42. package/dist/routes/record.js +4 -5
  43. package/dist/row-permissions.js +1 -1
  44. package/dist/sql-parts.d.ts +4 -0
  45. package/dist/sql-parts.js +1 -1
  46. package/dist/write-pipeline.js +5 -5
  47. package/dist/write-shared.d.ts +13 -0
  48. package/dist/write-shared.js +2 -2
  49. package/dist/write-update.js +1 -1
  50. package/package.json +4 -4
@@ -0,0 +1,221 @@
1
+ import { z } from "zod";
2
+ //#region src/batch/schema.d.ts
3
+ /** `{ ops: [...] }`; `{ operations: [...] }` is accepted too, for clients written against that name. */
4
+ export declare const batchBody: z.ZodPipe<z.ZodUnion<readonly [z.ZodObject<{
5
+ ops: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
6
+ op: z.ZodLiteral<"create">;
7
+ resource: z.ZodString;
8
+ data: z.ZodRecord<z.ZodString, z.ZodUnknown>;
9
+ ref: z.ZodOptional<z.ZodString>;
10
+ }, z.core.$strip>, z.ZodObject<{
11
+ op: z.ZodLiteral<"update">;
12
+ resource: z.ZodString;
13
+ key: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodObject<{
14
+ $ref: z.ZodString;
15
+ field: z.ZodOptional<z.ZodString>;
16
+ }, z.core.$strict>]>>, z.ZodObject<{
17
+ $ref: z.ZodString;
18
+ field: z.ZodOptional<z.ZodString>;
19
+ }, z.core.$strict>]>;
20
+ etag: z.ZodOptional<z.ZodString>;
21
+ data: z.ZodRecord<z.ZodString, z.ZodUnknown>;
22
+ }, z.core.$strip>, z.ZodObject<{
23
+ op: z.ZodLiteral<"delete">;
24
+ resource: z.ZodString;
25
+ key: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodObject<{
26
+ $ref: z.ZodString;
27
+ field: z.ZodOptional<z.ZodString>;
28
+ }, z.core.$strict>]>>, z.ZodObject<{
29
+ $ref: z.ZodString;
30
+ field: z.ZodOptional<z.ZodString>;
31
+ }, z.core.$strict>]>;
32
+ etag: z.ZodOptional<z.ZodString>;
33
+ }, z.core.$strip>, z.ZodObject<{
34
+ op: z.ZodLiteral<"reorder">;
35
+ resource: z.ZodString;
36
+ field: z.ZodString;
37
+ keys: z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodObject<{
38
+ $ref: z.ZodString;
39
+ field: z.ZodOptional<z.ZodString>;
40
+ }, z.core.$strict>]>>, z.ZodObject<{
41
+ $ref: z.ZodString;
42
+ field: z.ZodOptional<z.ZodString>;
43
+ }, z.core.$strict>]>>;
44
+ start: z.ZodOptional<z.ZodNumber>;
45
+ etags: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
46
+ }, z.core.$strip>], "op">>;
47
+ }, z.core.$strip>, z.ZodObject<{
48
+ operations: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
49
+ op: z.ZodLiteral<"create">;
50
+ resource: z.ZodString;
51
+ data: z.ZodRecord<z.ZodString, z.ZodUnknown>;
52
+ ref: z.ZodOptional<z.ZodString>;
53
+ }, z.core.$strip>, z.ZodObject<{
54
+ op: z.ZodLiteral<"update">;
55
+ resource: z.ZodString;
56
+ key: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodObject<{
57
+ $ref: z.ZodString;
58
+ field: z.ZodOptional<z.ZodString>;
59
+ }, z.core.$strict>]>>, z.ZodObject<{
60
+ $ref: z.ZodString;
61
+ field: z.ZodOptional<z.ZodString>;
62
+ }, z.core.$strict>]>;
63
+ etag: z.ZodOptional<z.ZodString>;
64
+ data: z.ZodRecord<z.ZodString, z.ZodUnknown>;
65
+ }, z.core.$strip>, z.ZodObject<{
66
+ op: z.ZodLiteral<"delete">;
67
+ resource: z.ZodString;
68
+ key: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodObject<{
69
+ $ref: z.ZodString;
70
+ field: z.ZodOptional<z.ZodString>;
71
+ }, z.core.$strict>]>>, z.ZodObject<{
72
+ $ref: z.ZodString;
73
+ field: z.ZodOptional<z.ZodString>;
74
+ }, z.core.$strict>]>;
75
+ etag: z.ZodOptional<z.ZodString>;
76
+ }, z.core.$strip>, z.ZodObject<{
77
+ op: z.ZodLiteral<"reorder">;
78
+ resource: z.ZodString;
79
+ field: z.ZodString;
80
+ keys: z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodObject<{
81
+ $ref: z.ZodString;
82
+ field: z.ZodOptional<z.ZodString>;
83
+ }, z.core.$strict>]>>, z.ZodObject<{
84
+ $ref: z.ZodString;
85
+ field: z.ZodOptional<z.ZodString>;
86
+ }, z.core.$strict>]>>;
87
+ start: z.ZodOptional<z.ZodNumber>;
88
+ etags: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
89
+ }, z.core.$strip>], "op">>;
90
+ }, z.core.$strip>]>, z.ZodTransform<{
91
+ ops: ({
92
+ op: "create";
93
+ resource: string;
94
+ data: Record<string, unknown>;
95
+ ref?: string | undefined;
96
+ } | {
97
+ op: "update";
98
+ resource: string;
99
+ key: string | number | {
100
+ $ref: string;
101
+ field?: string | undefined;
102
+ } | (string | number | {
103
+ $ref: string;
104
+ field?: string | undefined;
105
+ })[];
106
+ data: Record<string, unknown>;
107
+ etag?: string | undefined;
108
+ } | {
109
+ op: "delete";
110
+ resource: string;
111
+ key: string | number | {
112
+ $ref: string;
113
+ field?: string | undefined;
114
+ } | (string | number | {
115
+ $ref: string;
116
+ field?: string | undefined;
117
+ })[];
118
+ etag?: string | undefined;
119
+ } | {
120
+ op: "reorder";
121
+ resource: string;
122
+ field: string;
123
+ keys: (string | number | {
124
+ $ref: string;
125
+ field?: string | undefined;
126
+ } | (string | number | {
127
+ $ref: string;
128
+ field?: string | undefined;
129
+ })[])[];
130
+ start?: number | undefined;
131
+ etags?: Record<string, string> | undefined;
132
+ })[];
133
+ }, {
134
+ ops: ({
135
+ op: "create";
136
+ resource: string;
137
+ data: Record<string, unknown>;
138
+ ref?: string | undefined;
139
+ } | {
140
+ op: "update";
141
+ resource: string;
142
+ key: string | number | {
143
+ $ref: string;
144
+ field?: string | undefined;
145
+ } | (string | number | {
146
+ $ref: string;
147
+ field?: string | undefined;
148
+ })[];
149
+ data: Record<string, unknown>;
150
+ etag?: string | undefined;
151
+ } | {
152
+ op: "delete";
153
+ resource: string;
154
+ key: string | number | {
155
+ $ref: string;
156
+ field?: string | undefined;
157
+ } | (string | number | {
158
+ $ref: string;
159
+ field?: string | undefined;
160
+ })[];
161
+ etag?: string | undefined;
162
+ } | {
163
+ op: "reorder";
164
+ resource: string;
165
+ field: string;
166
+ keys: (string | number | {
167
+ $ref: string;
168
+ field?: string | undefined;
169
+ } | (string | number | {
170
+ $ref: string;
171
+ field?: string | undefined;
172
+ })[])[];
173
+ start?: number | undefined;
174
+ etags?: Record<string, string> | undefined;
175
+ })[];
176
+ } | {
177
+ operations: ({
178
+ op: "create";
179
+ resource: string;
180
+ data: Record<string, unknown>;
181
+ ref?: string | undefined;
182
+ } | {
183
+ op: "update";
184
+ resource: string;
185
+ key: string | number | {
186
+ $ref: string;
187
+ field?: string | undefined;
188
+ } | (string | number | {
189
+ $ref: string;
190
+ field?: string | undefined;
191
+ })[];
192
+ data: Record<string, unknown>;
193
+ etag?: string | undefined;
194
+ } | {
195
+ op: "delete";
196
+ resource: string;
197
+ key: string | number | {
198
+ $ref: string;
199
+ field?: string | undefined;
200
+ } | (string | number | {
201
+ $ref: string;
202
+ field?: string | undefined;
203
+ })[];
204
+ etag?: string | undefined;
205
+ } | {
206
+ op: "reorder";
207
+ resource: string;
208
+ field: string;
209
+ keys: (string | number | {
210
+ $ref: string;
211
+ field?: string | undefined;
212
+ } | (string | number | {
213
+ $ref: string;
214
+ field?: string | undefined;
215
+ })[])[];
216
+ start?: number | undefined;
217
+ etags?: Record<string, string> | undefined;
218
+ })[];
219
+ }>>;
220
+ export type BatchOperation = z.output<typeof batchBody>['ops'][number];
221
+ //#endregion
@@ -1,6 +1,6 @@
1
1
  import { notFound } from "../problem.js";
2
- import { parseParams } from "../params.js";
3
2
  import { readTransaction } from "../transactions.js";
3
+ import { parseParams } from "../params.js";
4
4
  import { commentAccess, mayRead, readableRecord, requireSignedIn, userSessions } from "./comment-access.js";
5
5
  import { z } from "zod";
6
6
  //#region src/comments/mentionable.ts
@@ -1,7 +1,7 @@
1
1
  import { notFound } from "../problem.js";
2
2
  import { tenantScope } from "../tenant.js";
3
- import { parseParams } from "../params.js";
4
3
  import { readTransaction } from "../transactions.js";
4
+ import { parseParams } from "../params.js";
5
5
  import { commentsTable } from "./comments-sql.js";
6
6
  import { commentAccess, readableRecord } from "./comment-access.js";
7
7
  import { commentColumns, commentItem, namedUsers } from "./comment-item.js";
@@ -2,9 +2,9 @@ import { aiModel } from "./ai/ai-model.js";
2
2
  import { hasAiActions, hasAiFields } from "./ai/ai-fields.js";
3
3
  import { unauthorized } from "./problem.js";
4
4
  import { fillHook } from "./ai/fill-hook.js";
5
- import { createErrorHandler } from "./error-handler.js";
6
5
  import { isCaptured } from "./changes/capture-sql.js";
7
6
  import { wakeDispatch } from "./changes/actor.js";
7
+ import { createErrorHandler } from "./error-handler.js";
8
8
  import { assistantRecords } from "./assistant/records.js";
9
9
  import { fillJob } from "./ai/fill-job.js";
10
10
  import { assistantSettings } from "./assistant/assistant-settings.js";
@@ -1,6 +1,6 @@
1
1
  import { HttpProblem, problemResponse } from "./problem.js";
2
- import { QueryError } from "@protobase/query";
3
2
  import { HTTPException } from "hono/http-exception";
3
+ import { QueryError } from "@protobase/query";
4
4
  //#region src/error-handler.ts
5
5
  const titles = {
6
6
  400: "Bad Request",
@@ -1,10 +1,10 @@
1
1
  import { HttpProblem, forbidden, notFound } from "../problem.js";
2
- import { decodeKeyText } from "../key.js";
3
- import { downloadExpiry, readDownloadUrl } from "./download-url.js";
2
+ import { readTransaction } from "../transactions.js";
3
+ import { fetchRecord } from "../records.js";
4
4
  import { contentDisposition, downloadName, servedType } from "./media-types.js";
5
5
  import { isFilePath, parseUri, tenantSegment, variantPaths } from "./uri.js";
6
- import { fetchRecord } from "../records.js";
7
- import { readTransaction } from "../transactions.js";
6
+ import { downloadExpiry, readDownloadUrl } from "./download-url.js";
7
+ import { decodeKeyText } from "../key.js";
8
8
  //#region src/files/download.ts
9
9
  const gone = () => notFound("There is no such file");
10
10
  /** One `bytes=start-end` range, inclusive; `undefined` for none, `false` for one that cannot be served. */
@@ -1,7 +1,7 @@
1
- import { downloadExpiry, signedDownloadUrl } from "./download-url.js";
2
1
  import { servedType } from "./media-types.js";
3
2
  import { externalFile, parseExternalUrl } from "./external-url.js";
4
3
  import { parseUri, variantPaths } from "./uri.js";
4
+ import { downloadExpiry, signedDownloadUrl } from "./download-url.js";
5
5
  import { encodeKey } from "@protobase/schema/internal";
6
6
  //#region src/files/present.ts
7
7
  const linker = async (files, access, row, field, ref, expires) => {
@@ -7,5 +7,5 @@ import { ListParams, RecordPage, ToolRecords } from "../assistant/records.js";
7
7
  * in the REST API. A refusal or a missing record rejects with an `HttpProblem`, which becomes the function's response
8
8
  * when it is not caught.
9
9
  */
10
- export type FunctionRecords = ToolRecords;
10
+ export type FunctionRecords = Omit<ToolRecords, 'batch'>;
11
11
  //#endregion
@@ -1,6 +1,9 @@
1
1
  import { assistantRecords } from "../assistant/records.js";
2
2
  //#region src/functions/records.ts
3
- /** `FunctionRecords` over the admin's resources for `session`. */
4
- const callerRecords = (deps, session) => assistantRecords(deps, session);
3
+ /** `FunctionRecords` over the admin's resources for `session`; the batch is the MCP tools' alone. */
4
+ const callerRecords = (deps, session) => {
5
+ const { batch: _batch, ...records } = assistantRecords(deps, session);
6
+ return records;
7
+ };
5
8
  //#endregion
6
9
  export { callerRecords };
@@ -1,10 +1,10 @@
1
1
  import { notFound } from "../problem.js";
2
2
  import { tenantScope } from "../tenant.js";
3
3
  import { requestAccess, requireOperation } from "../request-access.js";
4
- import { parseParams } from "../params.js";
5
- import { fetchReadable } from "../fetch-readable.js";
6
- import { readTransaction } from "../transactions.js";
7
4
  import { quoteIdent } from "../changes/capture-sql.js";
5
+ import { readTransaction } from "../transactions.js";
6
+ import { fetchReadable } from "../fetch-readable.js";
7
+ import { parseParams } from "../params.js";
8
8
  import { encodeKey } from "@protobase/schema/internal";
9
9
  import { z } from "zod";
10
10
  import { sql } from "kysely";
package/dist/index.d.ts CHANGED
@@ -34,6 +34,9 @@ import { MapOptions, MapSettings, mapSettings, mapStyleUrl, mapStyleVariable } f
34
34
  import { PluginOption, PluginRef, beforeSignInPluginsVariable, pluginOptions, pluginsBeforeSignIn, pluginsFor, pluginsVariable } from "./plugins/plugin-settings.js";
35
35
  import { ResourceSource, configExports } from "./resource-source.js";
36
36
  import { SourceOption, SourceRef, checkSourceNames, sourceOptions, sourcesFor, sourcesVariable } from "./sources/source-settings.js";
37
+ import { HttpProblem, MissingCredentials, badRequest, forbidden, notFound, unauthorized } from "./problem.js";
38
+ import { BatchOperation } from "./batch/schema.js";
39
+ import { BatchResult } from "./batch/run-batch.js";
37
40
  import { ListParams, RecordKeyInput, RecordPage, ToolRecord, ToolRecords } from "./assistant/records.js";
38
41
  import { FunctionRecords } from "./functions/records.js";
39
42
  import { ApiFunction, CorsOptions, FunctionApp, FunctionCaller, FunctionContext, FunctionHandler, FunctionOptions, FunctionSource, KeyFunctionContext, ProtectedFunctionOptions, PublicFunctionContext, PublicFunctionHandler, PublicFunctionOptions, defineFunction } from "./functions/define-function.js";
@@ -53,7 +56,6 @@ import { checkViewQueries } from "./check-view-queries.js";
53
56
  import { ProjectConfig, defineConfig, mergeConfig } from "./project-config.js";
54
57
  import { consoleAuditQueue } from "./audit/console-queue.js";
55
58
  import { JwtOptions, JwtVerifyOptions, jwtAuthenticator, jwtVerifier } from "./auth/jwt.js";
56
- import { HttpProblem, MissingCredentials, badRequest, forbidden, notFound, unauthorized } from "./problem.js";
57
59
  import { TrustedApp, withTrustedApps } from "./better-auth/app-tokens.js";
58
60
  import { BetterAuthAuthenticator, BetterAuthAuthenticatorOptions, betterAuthAuthenticator, betterAuthTokens } from "./better-auth/authenticator.js";
59
61
  import { parseRoles } from "./better-auth/parse-roles.js";
@@ -93,6 +95,7 @@ import { getRecordTool, listRecordsTool, listResourcesTool, readRecordTools } fr
93
95
  import { WriteRecordToolsInput } from "./assistant/write-tool-limits.js";
94
96
  import { createRecordTool, updateRecordTool, writeRecordTools } from "./assistant/write-record-tools.js";
95
97
  import { deleteRecordTool } from "./assistant/delete-record-tool.js";
98
+ import { batchWriteTool } from "./assistant/batch-write-tool.js";
96
99
  import { McpServerInput, mcpServer } from "./mcp/mcp-server.js";
97
100
  import { McpToolsInput, mcpTools } from "./mcp/mcp-tools.js";
98
101
  import { McpGateInput, mcpGate, sessionOf } from "./mcp/mcp-gate.js";
@@ -130,4 +133,4 @@ import { checkJobsSchema, jobsSchema, jobsSchemaMigration } from "./jobs/schema.
130
133
  import { MobileRelease, ReleaseFile, ServedReleaseFile, composeRelease, releaseManifest } from "./mobile-release/release.js";
131
134
  import { MobileReleaseAppInput, OfferedRelease, mobileReleaseApp } from "./mobile-release/release-app.js";
132
135
  import { mobileSigningKeyVariable, readSigningKey } from "./mobile-release/signing-key.js";
133
- export { type Admin, type AdminAuth, type AdminOptions, type ApiFunction, type ApiKeys, type ApiKeysOptions, type AppIcons, type AppIdentity, type ApplyOptions, type ApplyResult, type ApprovalAnswer, type ApprovalRequest, type AssistantBackend, type AssistantOptions, type AssistantSettings, type AssistantTool, type AuditEvent, type AuditQueue, type Authenticator, type BetterAuthAuthenticator, type BetterAuthAuthenticatorOptions, type Caller, type CallerOptions, type CapturedRow, type CascadingKey, type ChatMessage, type ChatTextPart, type CheckAiInput, type CleanupEntry, type CleanupReport, type CleanupSchedule, type CoalescedChange, type CommentItem, type CommentUsers, type Completion, type CompletionOptions, type Conversation, type ConversationRecord, type ConversationStore, type ConversationsOptions, type CorsOptions, type CorsOrigins, type CreateAdminInput, type CreateAuthOptions, type DrainResult, type EmailComponent, type EmailOptions, type EmailTemplate, type EncryptionStatus, type EncryptionTools, type EncryptionToolsInput, type EnqueueOptions, type ErrorReporter, type ErrorReportingOptions, type ErrorReportingSettings, type EventData, type EventsOptions, FatalJobError, type FieldApplied, type FieldStatus, type FileCleanupInput, type FileLimits, type FileObject, type FileProvider, type FileRef, type FileStore, type FileVariantObject, type FilesOptions, type FunctionApp, type FunctionCaller, type FunctionContext, type FunctionEnv, type FunctionHandler, type FunctionOptions, type FunctionRecords, type FunctionSocket, type FunctionSource, type HistoryOptions, HttpProblem, type IssueTokenOptions, type JobContext, type JobDefinition, type JobOptions, type JobsRuntime, type JwtOptions, type JwtVerifyOptions, type KeyFunctionContext, type LinkedAccount, type ListParams, type LocalFilesOptions, type MailMessage, type Mailer, type MapLayer, type MapOptions, type MapSettings, type McpGateInput, type McpHandlerInput, type McpRoutesInput, type McpServerInput, type McpToolsInput, type McpWrites, type MemberInput, MissingCredentials, type MobileConfig, type MobileRelease, type MobileReleaseAppInput, ModelError, type ModelSettings, type NewOrganization, type NewUser, type OfferedRelease, type OperatorProvider, type OrganizationRole, type OrganizationsOptions, type PipelineHook, type PlatformSignIn, type PluginOption, type PluginRef, type PngIcon, type ProjectConfig, type ProtectedFunctionOptions, type PublicFunctionContext, type PublicFunctionEnv, type PublicFunctionHandler, type PublicFunctionOptions, type QueryOptions, type QueryResult, type ReadableResources, type ReasoningDetail, type ReasoningEffort, type RebindOption, type RecordKeyInput, type RecordPage, type ReleaseFile, type RenderedEmail, type ResourceChange, type ResourceSource, type RoleDefinition, type RolesInput, type RunContext, type RuntimeOptions, type S3Bucket, type S3FilesOptions, type S3ListPage, type S3Object, type ScanGuardMode, type ScheduledDelete, type ServedReleaseFile, type Session, type SessionOrganization, type Sharp, type SignInPolicy, type SignInRule, type SignatureOptions, type SocketEvents, type SourceOption, type SourceRef, type StaffAccessRule, type StaffSignIn, type StandardSchema, type StandardWebhookOptions, type StartJobsOptions, type StoreFileInput, type StoredMember, type StoredObject, type StoredOrganization, type StoredUser, type StrayValues, type SubscriptionDefinition, type SubscriptionEvent, type SubscriptionOptions, type TenantValue, type ToolAnnotations, type ToolCall, type ToolContext, type ToolRecord, type ToolRecords, type ToolSpec, type TrustedApp, type TurnOptions, type UnreadableEntry, type User, type UserCreatedHook, type ViewSource, type WebhooksOptions, type WidgetOptions, type WriteEvent, type WriteOperation, type WriteRecordToolsInput, addAppRoleToOwners, addMember, apiKeyCaller, apiKeySettings, apiKeyVariables, aspectRatio, assistantProtocolRoutes, assistantRoles, assistantSettings, assistantVariables, authSchemaMigration, authStoreTables, backgroundSettled, badRequest, beforeSignInPluginsVariable, betterAuthAuthenticator, betterAuthTokens, capSocketMessages, changesMigration, checkAi, checkAuthSchema, checkChanges, checkComments, checkComputed, checkJobsSchema, checkQueryRunner, checkSourceNames, checkViewQueries, checkWebhooksSchema, coalesce, commentsMigration, composeRelease, computedMigration, configExports, consoleAuditQueue, conversationKey, createAdmin, createAuth, createConversations, createEncryptionTools, createFileCleanup, createOrganization, createRecordTool, createUser, defaultAppName, defaultSignInPolicy, defineConfig, defineEmail, defineFunction, defineJob, defineTool, deleteRecordTool, deleteUser, errorReportingSettings, errorReportingVariable, eventMatcher, fileConversationStore, fileSize, fileType, forbidden, formatUri, functionApp, getRecordTool, goTruePath, handleDroppedConnections, hasUsers, honorSocketMessageCaps, imageSize, isBackgroundWork, isCaptured, isJobDefinition, isOAuthWellKnownPath, isSchedule, issueToken, jobDefinitions, jobsDrainApp, jobsSchema, jobsSchemaMigration, jwtAuthenticator, jwtVerifier, limitedFileStore, listOrganizations, listRecordsTool, listResourcesTool, listUsers, localFileStore, localFiles, mapSettings, mapStyleUrl, mapStyleVariable, maxTokenTtlSeconds, maxWidgetPropsBytes, mcpGate, mcpHandler, mcpRoutes, mcpServer, mcpToolContext, mcpTools, mergeConfig, migrationCommand, mobileReleaseApp, mobileSigningKeyVariable, newWebhookSecret, normalizeRoles, notFound, oauthWellKnownPaths, objectKey, parseColumns, parseRoles, passwordLength, pluginOptions, pluginsBeforeSignIn, pluginsFor, pluginsVariable, pngIcons, processor, queryRunnerMigration, readJson, readOnlyQueryTool, readOperatorSettings, readOutbox, readPlatformSignIn, readRecordTools, readSigningKey, readWriteQueryTool, readableResources, realtimeLimits, recordOf, releaseManifest, removeMember, renderVariant, requestApproval, requireEnv, resourceChange, roleChoices, runInBackground, runReadOnlyQuery, runReadWriteQuery, runTurn, runtimeUrl, runtimeVariable, s3FileStore, s3Files, seesAssistant, seesRuntime, sessionOf, setMemberRoles, setUserBanned, setUserRole, signInPolicyMethods, socketMessageCapOf, sourceOptions, sourcesFor, sourcesVariable, startErrorReporting, startJobs, storageCleanupSchedule, storageProvider, storeFile, storeUsage, streamChatCompletion, subscription, supabasePath, thumbHash, unauthorized, updateRecordTool, variantPath, verifySignature, verifyStandardWebhook, waitUntil, webauthnPath, webhooks, webhooksMigration, widget, withCacheBreakpoints, withTrustedApps, writeRecordTools };
136
+ export { type Admin, type AdminAuth, type AdminOptions, type ApiFunction, type ApiKeys, type ApiKeysOptions, type AppIcons, type AppIdentity, type ApplyOptions, type ApplyResult, type ApprovalAnswer, type ApprovalRequest, type AssistantBackend, type AssistantOptions, type AssistantSettings, type AssistantTool, type AuditEvent, type AuditQueue, type Authenticator, type BatchOperation, type BatchResult, type BetterAuthAuthenticator, type BetterAuthAuthenticatorOptions, type Caller, type CallerOptions, type CapturedRow, type CascadingKey, type ChatMessage, type ChatTextPart, type CheckAiInput, type CleanupEntry, type CleanupReport, type CleanupSchedule, type CoalescedChange, type CommentItem, type CommentUsers, type Completion, type CompletionOptions, type Conversation, type ConversationRecord, type ConversationStore, type ConversationsOptions, type CorsOptions, type CorsOrigins, type CreateAdminInput, type CreateAuthOptions, type DrainResult, type EmailComponent, type EmailOptions, type EmailTemplate, type EncryptionStatus, type EncryptionTools, type EncryptionToolsInput, type EnqueueOptions, type ErrorReporter, type ErrorReportingOptions, type ErrorReportingSettings, type EventData, type EventsOptions, FatalJobError, type FieldApplied, type FieldStatus, type FileCleanupInput, type FileLimits, type FileObject, type FileProvider, type FileRef, type FileStore, type FileVariantObject, type FilesOptions, type FunctionApp, type FunctionCaller, type FunctionContext, type FunctionEnv, type FunctionHandler, type FunctionOptions, type FunctionRecords, type FunctionSocket, type FunctionSource, type HistoryOptions, HttpProblem, type IssueTokenOptions, type JobContext, type JobDefinition, type JobOptions, type JobsRuntime, type JwtOptions, type JwtVerifyOptions, type KeyFunctionContext, type LinkedAccount, type ListParams, type LocalFilesOptions, type MailMessage, type Mailer, type MapLayer, type MapOptions, type MapSettings, type McpGateInput, type McpHandlerInput, type McpRoutesInput, type McpServerInput, type McpToolsInput, type McpWrites, type MemberInput, MissingCredentials, type MobileConfig, type MobileRelease, type MobileReleaseAppInput, ModelError, type ModelSettings, type NewOrganization, type NewUser, type OfferedRelease, type OperatorProvider, type OrganizationRole, type OrganizationsOptions, type PipelineHook, type PlatformSignIn, type PluginOption, type PluginRef, type PngIcon, type ProjectConfig, type ProtectedFunctionOptions, type PublicFunctionContext, type PublicFunctionEnv, type PublicFunctionHandler, type PublicFunctionOptions, type QueryOptions, type QueryResult, type ReadableResources, type ReasoningDetail, type ReasoningEffort, type RebindOption, type RecordKeyInput, type RecordPage, type ReleaseFile, type RenderedEmail, type ResourceChange, type ResourceSource, type RoleDefinition, type RolesInput, type RunContext, type RuntimeOptions, type S3Bucket, type S3FilesOptions, type S3ListPage, type S3Object, type ScanGuardMode, type ScheduledDelete, type ServedReleaseFile, type Session, type SessionOrganization, type Sharp, type SignInPolicy, type SignInRule, type SignatureOptions, type SocketEvents, type SourceOption, type SourceRef, type StaffAccessRule, type StaffSignIn, type StandardSchema, type StandardWebhookOptions, type StartJobsOptions, type StoreFileInput, type StoredMember, type StoredObject, type StoredOrganization, type StoredUser, type StrayValues, type SubscriptionDefinition, type SubscriptionEvent, type SubscriptionOptions, type TenantValue, type ToolAnnotations, type ToolCall, type ToolContext, type ToolRecord, type ToolRecords, type ToolSpec, type TrustedApp, type TurnOptions, type UnreadableEntry, type User, type UserCreatedHook, type ViewSource, type WebhooksOptions, type WidgetOptions, type WriteEvent, type WriteOperation, type WriteRecordToolsInput, addAppRoleToOwners, addMember, apiKeyCaller, apiKeySettings, apiKeyVariables, aspectRatio, assistantProtocolRoutes, assistantRoles, assistantSettings, assistantVariables, authSchemaMigration, authStoreTables, backgroundSettled, badRequest, batchWriteTool, beforeSignInPluginsVariable, betterAuthAuthenticator, betterAuthTokens, capSocketMessages, changesMigration, checkAi, checkAuthSchema, checkChanges, checkComments, checkComputed, checkJobsSchema, checkQueryRunner, checkSourceNames, checkViewQueries, checkWebhooksSchema, coalesce, commentsMigration, composeRelease, computedMigration, configExports, consoleAuditQueue, conversationKey, createAdmin, createAuth, createConversations, createEncryptionTools, createFileCleanup, createOrganization, createRecordTool, createUser, defaultAppName, defaultSignInPolicy, defineConfig, defineEmail, defineFunction, defineJob, defineTool, deleteRecordTool, deleteUser, errorReportingSettings, errorReportingVariable, eventMatcher, fileConversationStore, fileSize, fileType, forbidden, formatUri, functionApp, getRecordTool, goTruePath, handleDroppedConnections, hasUsers, honorSocketMessageCaps, imageSize, isBackgroundWork, isCaptured, isJobDefinition, isOAuthWellKnownPath, isSchedule, issueToken, jobDefinitions, jobsDrainApp, jobsSchema, jobsSchemaMigration, jwtAuthenticator, jwtVerifier, limitedFileStore, listOrganizations, listRecordsTool, listResourcesTool, listUsers, localFileStore, localFiles, mapSettings, mapStyleUrl, mapStyleVariable, maxTokenTtlSeconds, maxWidgetPropsBytes, mcpGate, mcpHandler, mcpRoutes, mcpServer, mcpToolContext, mcpTools, mergeConfig, migrationCommand, mobileReleaseApp, mobileSigningKeyVariable, newWebhookSecret, normalizeRoles, notFound, oauthWellKnownPaths, objectKey, parseColumns, parseRoles, passwordLength, pluginOptions, pluginsBeforeSignIn, pluginsFor, pluginsVariable, pngIcons, processor, queryRunnerMigration, readJson, readOnlyQueryTool, readOperatorSettings, readOutbox, readPlatformSignIn, readRecordTools, readSigningKey, readWriteQueryTool, readableResources, realtimeLimits, recordOf, releaseManifest, removeMember, renderVariant, requestApproval, requireEnv, resourceChange, roleChoices, runInBackground, runReadOnlyQuery, runReadWriteQuery, runTurn, runtimeUrl, runtimeVariable, s3FileStore, s3Files, seesAssistant, seesRuntime, sessionOf, setMemberRoles, setUserBanned, setUserRole, signInPolicyMethods, socketMessageCapOf, sourceOptions, sourcesFor, sourcesVariable, startErrorReporting, startJobs, storageCleanupSchedule, storageProvider, storeFile, storeUsage, streamChatCompletion, subscription, supabasePath, thumbHash, unauthorized, updateRecordTool, variantPath, verifySignature, verifyStandardWebhook, waitUntil, webauthnPath, webhooks, webhooksMigration, widget, withCacheBreakpoints, withTrustedApps, writeRecordTools };
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { HttpProblem, MissingCredentials, badRequest, forbidden, notFound, unauthorized } from "./problem.js";
2
- import { formatUri, variantPath } from "./files/uri.js";
3
2
  import { checkJobsSchema, jobsSchema, jobsSchemaMigration } from "./jobs/schema.js";
4
3
  import { isCaptured } from "./changes/capture-sql.js";
4
+ import { formatUri, variantPath } from "./files/uri.js";
5
5
  import { isSchedule } from "./jobs/schedule.js";
6
6
  import { defineJob, isJobDefinition, jobDefinitions } from "./jobs/define-job.js";
7
7
  import { FatalJobError } from "./jobs/run-job.js";
@@ -41,6 +41,7 @@ import { mcpServer } from "./mcp/mcp-server.js";
41
41
  import { getRecordTool, listRecordsTool, listResourcesTool, readRecordTools } from "./assistant/record-tools.js";
42
42
  import { deleteRecordTool } from "./assistant/delete-record-tool.js";
43
43
  import { createRecordTool, updateRecordTool, writeRecordTools } from "./assistant/write-record-tools.js";
44
+ import { batchWriteTool } from "./assistant/batch-write-tool.js";
44
45
  import { mcpTools } from "./mcp/mcp-tools.js";
45
46
  import { addAppRoleToOwners, addMember, createOrganization, listOrganizations, removeMember, setMemberRoles } from "./better-auth/organizations/host.js";
46
47
  import { createUser, deleteUser, hasUsers, listUsers, roleChoices, setUserBanned, setUserRole } from "./better-auth/users.js";
@@ -99,4 +100,4 @@ import { jobsDrainApp } from "./jobs/drain-route.js";
99
100
  import { composeRelease, releaseManifest } from "./mobile-release/release.js";
100
101
  import { mobileReleaseApp } from "./mobile-release/release-app.js";
101
102
  import { mobileSigningKeyVariable, readSigningKey } from "./mobile-release/signing-key.js";
102
- export { FatalJobError, HttpProblem, MissingCredentials, ModelError, addAppRoleToOwners, addMember, apiKeyCaller, apiKeySettings, apiKeyVariables, aspectRatio, assistantProtocolRoutes, assistantRoles, assistantSettings, assistantVariables, authSchemaMigration, authStoreTables, backgroundSettled, badRequest, beforeSignInPluginsVariable, betterAuthAuthenticator, betterAuthTokens, capSocketMessages, changesMigration, checkAi, checkAuthSchema, checkChanges, checkComments, checkComputed, checkJobsSchema, checkQueryRunner, checkSourceNames, checkViewQueries, checkWebhooksSchema, coalesce, commentsMigration, composeRelease, computedMigration, configExports, consoleAuditQueue, conversationKey, createAdmin, createAuth, createConversations, createEncryptionTools, createFileCleanup, createOrganization, createRecordTool, createUser, defaultAppName, defaultSignInPolicy, defineConfig, defineEmail, defineFunction, defineJob, defineTool, deleteRecordTool, deleteUser, errorReportingSettings, errorReportingVariable, eventMatcher, fileConversationStore, fileSize, fileType, forbidden, formatUri, functionApp, getRecordTool, goTruePath, handleDroppedConnections, hasUsers, honorSocketMessageCaps, imageSize, isBackgroundWork, isCaptured, isJobDefinition, isOAuthWellKnownPath, isSchedule, issueToken, jobDefinitions, jobsDrainApp, jobsSchema, jobsSchemaMigration, jwtAuthenticator, jwtVerifier, limitedFileStore, listOrganizations, listRecordsTool, listResourcesTool, listUsers, localFileStore, localFiles, mapSettings, mapStyleUrl, mapStyleVariable, maxTokenTtlSeconds, maxWidgetPropsBytes, mcpGate, mcpHandler, mcpRoutes, mcpServer, mcpToolContext, mcpTools, mergeConfig, migrationCommand, mobileReleaseApp, mobileSigningKeyVariable, newWebhookSecret, normalizeRoles, notFound, oauthWellKnownPaths, objectKey, parseColumns, parseRoles, passwordLength, pluginOptions, pluginsBeforeSignIn, pluginsFor, pluginsVariable, pngIcons, processor, queryRunnerMigration, readJson, readOnlyQueryTool, readOperatorSettings, readOutbox, readPlatformSignIn, readRecordTools, readSigningKey, readWriteQueryTool, readableResources, realtimeLimits, recordOf, releaseManifest, removeMember, renderVariant, requestApproval, requireEnv, resourceChange, roleChoices, runInBackground, runReadOnlyQuery, runReadWriteQuery, runTurn, runtimeUrl, runtimeVariable, s3FileStore, s3Files, seesAssistant, seesRuntime, sessionOf, setMemberRoles, setUserBanned, setUserRole, signInPolicyMethods, socketMessageCapOf, sourceOptions, sourcesFor, sourcesVariable, startErrorReporting, startJobs, storageCleanupSchedule, storageProvider, storeFile, storeUsage, streamChatCompletion, subscription, supabasePath, thumbHash, unauthorized, updateRecordTool, variantPath, verifySignature, verifyStandardWebhook, waitUntil, webauthnPath, webhooks, webhooksMigration, widget, withCacheBreakpoints, withTrustedApps, writeRecordTools };
103
+ export { FatalJobError, HttpProblem, MissingCredentials, ModelError, addAppRoleToOwners, addMember, apiKeyCaller, apiKeySettings, apiKeyVariables, aspectRatio, assistantProtocolRoutes, assistantRoles, assistantSettings, assistantVariables, authSchemaMigration, authStoreTables, backgroundSettled, badRequest, batchWriteTool, beforeSignInPluginsVariable, betterAuthAuthenticator, betterAuthTokens, capSocketMessages, changesMigration, checkAi, checkAuthSchema, checkChanges, checkComments, checkComputed, checkJobsSchema, checkQueryRunner, checkSourceNames, checkViewQueries, checkWebhooksSchema, coalesce, commentsMigration, composeRelease, computedMigration, configExports, consoleAuditQueue, conversationKey, createAdmin, createAuth, createConversations, createEncryptionTools, createFileCleanup, createOrganization, createRecordTool, createUser, defaultAppName, defaultSignInPolicy, defineConfig, defineEmail, defineFunction, defineJob, defineTool, deleteRecordTool, deleteUser, errorReportingSettings, errorReportingVariable, eventMatcher, fileConversationStore, fileSize, fileType, forbidden, formatUri, functionApp, getRecordTool, goTruePath, handleDroppedConnections, hasUsers, honorSocketMessageCaps, imageSize, isBackgroundWork, isCaptured, isJobDefinition, isOAuthWellKnownPath, isSchedule, issueToken, jobDefinitions, jobsDrainApp, jobsSchema, jobsSchemaMigration, jwtAuthenticator, jwtVerifier, limitedFileStore, listOrganizations, listRecordsTool, listResourcesTool, listUsers, localFileStore, localFiles, mapSettings, mapStyleUrl, mapStyleVariable, maxTokenTtlSeconds, maxWidgetPropsBytes, mcpGate, mcpHandler, mcpRoutes, mcpServer, mcpToolContext, mcpTools, mergeConfig, migrationCommand, mobileReleaseApp, mobileSigningKeyVariable, newWebhookSecret, normalizeRoles, notFound, oauthWellKnownPaths, objectKey, parseColumns, parseRoles, passwordLength, pluginOptions, pluginsBeforeSignIn, pluginsFor, pluginsVariable, pngIcons, processor, queryRunnerMigration, readJson, readOnlyQueryTool, readOperatorSettings, readOutbox, readPlatformSignIn, readRecordTools, readSigningKey, readWriteQueryTool, readableResources, realtimeLimits, recordOf, releaseManifest, removeMember, renderVariant, requestApproval, requireEnv, resourceChange, roleChoices, runInBackground, runReadOnlyQuery, runReadWriteQuery, runTurn, runtimeUrl, runtimeVariable, s3FileStore, s3Files, seesAssistant, seesRuntime, sessionOf, setMemberRoles, setUserBanned, setUserRole, signInPolicyMethods, socketMessageCapOf, sourceOptions, sourcesFor, sourcesVariable, startErrorReporting, startJobs, storageCleanupSchedule, storageProvider, storeFile, storeUsage, streamChatCompletion, subscription, supabasePath, thumbHash, unauthorized, updateRecordTool, variantPath, verifySignature, verifyStandardWebhook, waitUntil, webauthnPath, webhooks, webhooksMigration, widget, withCacheBreakpoints, withTrustedApps, writeRecordTools };
@@ -1,6 +1,6 @@
1
1
  import "./job-types.js";
2
- import { Db } from "@protobase/query";
3
2
  import "pg-boss";
3
+ import { Db } from "@protobase/query";
4
4
  //#region src/jobs/run-job.d.ts
5
5
  /** Thrown from a job's `run`, it fails the job now: the attempts it has left are not used. */
6
6
  export declare class FatalJobError extends Error {
@@ -1,9 +1,9 @@
1
1
  import { badRequest } from "./problem.js";
2
2
  import { checkedSort } from "./filter-input.js";
3
3
  import { readScope, requestAccess } from "./request-access.js";
4
- import { presentFiles } from "./files/present.js";
5
- import { exposeRow } from "./rows.js";
6
4
  import { readTransaction } from "./transactions.js";
5
+ import { exposeRow } from "./rows.js";
6
+ import { presentFiles } from "./files/present.js";
7
7
  import { cardPhotosErrors } from "./view-card-photos.js";
8
8
  import { cardPhotoLimit } from "@protobase/schema/internal";
9
9
  import { checkFilter, createWhere } from "@protobase/schema";
@@ -1,13 +1,13 @@
1
1
  import { checkedFilter, checkedSort } from "./filter-input.js";
2
2
  import { readScope, requestAccess, requireOperation } from "./request-access.js";
3
- import { deletedRows, listParams, pageSizeOf, parseParams, seekParams, selectedFields } from "./params.js";
3
+ import { readTransaction } from "./transactions.js";
4
4
  import { etagAlias } from "./sql-parts.js";
5
5
  import { etagOf } from "./etag.js";
6
- import { presentFiles } from "./files/present.js";
7
6
  import { exposeRow, pickFields } from "./rows.js";
7
+ import { presentFiles } from "./files/present.js";
8
+ import { deletedRows, listParams, pageSizeOf, parseParams, seekParams, selectedFields } from "./params.js";
8
9
  import { rowPermissions } from "./row-permissions.js";
9
10
  import { labelRequests, relatedLabels } from "./related-labels.js";
10
- import { readTransaction } from "./transactions.js";
11
11
  import { photosRequest, recordPhotos } from "./list-photos.js";
12
12
  import { countUpTo, estimateCount, listQuery, seekToPosition } from "@protobase/query";
13
13
  //#region src/list-service.ts
@@ -1,8 +1,8 @@
1
1
  import { checkedFilter } from "./filter-input.js";
2
2
  import { readScope, requestAccess, requireOperation } from "./request-access.js";
3
+ import { readTransaction } from "./transactions.js";
3
4
  import { parseParams, selectedFields } from "./params.js";
4
5
  import { labelRequests } from "./related-labels.js";
5
- import { readTransaction } from "./transactions.js";
6
6
  import { photosRequest } from "./list-photos.js";
7
7
  import { listRecords } from "./list-service.js";
8
8
  import { z } from "zod";
@@ -8,14 +8,11 @@ export type McpToolsInput = {
8
8
  /** Offers `run_read_only_query` to callers who see the assistant (`admin` or `ai`); it reads outside the access rules. */
9
9
  sql: boolean;
10
10
  /**
11
- * Offers `create_record`, `update_record` and `delete_record`, on the listed resources only when given `{ resources }`; each write
12
- * still needs the caller's role, and their approval in the client unless they hold one of `rolesWithoutApproval`.
11
+ * Offers `create_record`, `update_record`, `delete_record` and `batch_write`, on the listed resources only when given
12
+ * `{ resources }`; each write still needs the caller's role, and their approval in the client unless they hold one of
13
+ * `rolesWithoutApproval`.
13
14
  */
14
15
  writes: McpWrites;
15
16
  };
16
- /**
17
- * The default MCP tools for a caller: the record tools, the write tools when `writes` is on, and read-only SQL when `sql`
18
- * is on and the caller sees the assistant.
19
- */
20
17
  export declare const mcpTools: ({ db, sql, writes }: McpToolsInput) => (session: Session) => AssistantTool[];
21
18
  //#endregion
@@ -2,14 +2,16 @@ import { seesAssistant } from "../assistant/assistant-settings.js";
2
2
  import { readOnlyQueryTool } from "../assistant/query-tools.js";
3
3
  import { readRecordTools } from "../assistant/record-tools.js";
4
4
  import { writeRecordTools } from "../assistant/write-record-tools.js";
5
+ import { batchWriteTool } from "../assistant/batch-write-tool.js";
5
6
  //#region src/mcp/mcp-tools.ts
6
7
  /**
7
8
  * The default MCP tools for a caller: the record tools, the write tools when `writes` is on, and read-only SQL when `sql`
8
9
  * is on and the caller sees the assistant.
9
10
  */
11
+ const writeTools = (input) => [...writeRecordTools(input), batchWriteTool(input)];
10
12
  const mcpTools = ({ db, sql, writes }) => (session) => [
11
13
  ...readRecordTools(),
12
- ...writes === false ? [] : writeRecordTools(writes === true || !writes.resources ? {} : { resources: writes.resources }),
14
+ ...writes === false ? [] : writeTools(writes === true || !writes.resources ? {} : { resources: writes.resources }),
13
15
  ...sql && seesAssistant(session.user.roles) ? [readOnlyQueryTool(db)] : []
14
16
  ];
15
17
  //#endregion
package/dist/package.js CHANGED
@@ -1,4 +1,4 @@
1
1
  //#region package.json
2
- var version = "0.42.0";
2
+ var version = "0.43.0";
3
3
  //#endregion
4
4
  export { version };
@@ -1,10 +1,11 @@
1
1
  import { notFound } from "./problem.js";
2
2
  import { requestAccess, requireOperation, visibleFields, writableFields } from "./request-access.js";
3
- import { presentFiles } from "./files/present.js";
3
+ import { readTransaction } from "./transactions.js";
4
4
  import { pickFields } from "./rows.js";
5
5
  import { fetchReadable } from "./fetch-readable.js";
6
+ import { presentFiles } from "./files/present.js";
7
+ import { deletedRows } from "./params.js";
6
8
  import { rowPermissions } from "./row-permissions.js";
7
- import { readTransaction } from "./transactions.js";
8
9
  //#region src/read-service.ts
9
10
  /**
10
11
  * `edit` for fields the caller may change on this record, `read` for the rest (sensitive ones included); hidden fields
@@ -18,11 +19,13 @@ const fieldModes = (access, canUpdate) => {
18
19
  };
19
20
  /**
20
21
  * The record with this key as the caller may see it: readable fields only, inside the caller's tenant and row filter.
21
- * A key outside the tenant, outside the row filter, or failing a record-level read rule is a plain 404.
22
+ * A key outside the tenant, outside the row filter, or failing a record-level read rule is a plain 404. `showDeleted`
23
+ * also finds a soft-deleted record, and is refused on a resource without a soft delete once the caller may read it.
22
24
  */
23
- const readRecord = async (deps, entry, session, key, deleted = "hide") => {
25
+ const readRecord = async (deps, entry, session, key, showDeleted = false) => {
24
26
  const access = await requestAccess(deps, entry, session);
25
27
  requireOperation(access, "read");
28
+ const deleted = deletedRows(access.full, showDeleted);
26
29
  const names = Object.keys(access.model.fields);
27
30
  const found = await readTransaction(deps.db, deps.statementTimeoutMs, async (trx) => {
28
31
  const current = await fetchReadable(trx, access, key, deleted, {
@@ -1,5 +1,5 @@
1
- import { readTransaction } from "../transactions.js";
2
1
  import { quoteIdent, tableSql } from "../changes/capture-sql.js";
2
+ import { readTransaction } from "../transactions.js";
3
3
  import { callerSettings } from "../rest/caller-settings.js";
4
4
  import { filterSql } from "./change-filter.js";
5
5
  import { decodeKey, encodeKey } from "@protobase/schema/internal";
@@ -0,0 +1,5 @@
1
+ import "./types.js";
2
+ import "./registry.js";
3
+ import "./sql-parts.js";
4
+ import { FieldModel } from "@protobase/schema";
5
+ import { Db } from "@protobase/query";
@@ -1,5 +1,5 @@
1
- import { readTransaction, writeTransaction } from "../transactions.js";
2
1
  import { wakeDispatch } from "../changes/actor.js";
2
+ import { readTransaction, writeTransaction } from "../transactions.js";
3
3
  import { callerSettings } from "./caller-settings.js";
4
4
  import { restError } from "./rest-error.js";
5
5
  //#region src/rest/rest-context.ts
@@ -1,9 +1,9 @@
1
1
  import { badRequest, notFound } from "./problem.js";
2
2
  import { tenantScope } from "./tenant.js";
3
3
  import { requestAccess, requireOperation } from "./request-access.js";
4
+ import { readTransaction } from "./transactions.js";
4
5
  import { bindingOf } from "./encryption/binding.js";
5
6
  import { fetchReadable } from "./fetch-readable.js";
6
- import { readTransaction } from "./transactions.js";
7
7
  import { openText } from "./encryption/envelope-open.js";
8
8
  import { encodeKey } from "@protobase/schema/internal";
9
9
  //#region src/reveal-service.ts
@@ -1,6 +1,6 @@
1
+ import { runBatch } from "../batch/run-batch.js";
1
2
  import { parseParams } from "../params.js";
2
3
  import { batchBody } from "../batch/schema.js";
3
- import { runBatch } from "../batch/run-batch.js";
4
4
  import { Hono } from "hono";
5
5
  //#region src/routes/batch.ts
6
6
  /**
@@ -1,5 +1,5 @@
1
- import { listRecords } from "../list-service.js";
2
1
  import { runWrite } from "../write-pipeline.js";
2
+ import { listRecords } from "../list-service.js";
3
3
  import { facets, numericHistogram, timeSeries } from "../aggregate-service.js";
4
4
  import { aggregate } from "../aggregate-groups.js";
5
5
  import { mapRecords } from "../map-service.js";
@@ -1,9 +1,9 @@
1
1
  import { notFound } from "../problem.js";
2
- import { keyFromPath } from "../key.js";
3
- import { deletedRows, selectedFields } from "../params.js";
4
2
  import { pickFields } from "../rows.js";
5
- import { readRecord } from "../read-service.js";
6
3
  import { runWrite } from "../write-pipeline.js";
4
+ import { keyFromPath } from "../key.js";
5
+ import { selectedFields } from "../params.js";
6
+ import { readRecord } from "../read-service.js";
7
7
  import { auditOrigin } from "../audit/origin.js";
8
8
  import { returnPreference } from "./preferences.js";
9
9
  import { resolveTarget } from "./target.js";
@@ -22,8 +22,7 @@ const recordRoutes = (deps) => {
22
22
  if (c.req.param("key").endsWith(":history")) return c.json(await readHistory(deps, entry, c.get("session"), keyFromPath(c, entry, ":history"), c.req.query()));
23
23
  if (c.req.param("key").endsWith(":comments")) return c.json(await readComments(deps, entry, c.get("session"), keyFromPath(c, entry, ":comments"), c.req.query()));
24
24
  if (c.req.param("key").endsWith(":mentionable")) return c.json(await mentionable(deps, entry, c.get("session"), keyFromPath(c, entry, ":mentionable"), c.req.query()));
25
- const deleted = deletedRows(entry.model, c.req.query("show_deleted") === "true");
26
- const found = await readRecord(deps, entry, c.get("session"), keyFromPath(c, entry), deleted);
25
+ const found = await readRecord(deps, entry, c.get("session"), keyFromPath(c, entry), c.req.query("show_deleted") === "true");
27
26
  const columns = selectedFields({
28
27
  ...entry.model,
29
28
  fields: Object.fromEntries(Object.keys(found.record).map((name) => [name, entry.model.fields[name]]))
@@ -3,8 +3,8 @@ import { recordDecision } from "./request-access.js";
3
3
  import { aliasedColumn, columnId, scopeConditions, tableId, whereClause } from "./sql-parts.js";
4
4
  import { fetchRecord } from "./records.js";
5
5
  import { parentGuard } from "./parent-access.js";
6
- import { compileFilter } from "@protobase/query";
7
6
  import { sql } from "kysely";
7
+ import { compileFilter } from "@protobase/query";
8
8
  //#region src/row-permissions.ts
9
9
  const keyOf = (access, row) => JSON.stringify(access.full.primaryKey.map((name) => String(row[name])));
10
10
  const matching = async (trx, access, rows, filter) => {