@softr/sdk 0.0.56-alpha.1 → 0.0.56-alpha.2
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 +1 -31
- package/dist/action.js +1 -26
- package/dist/client.d.ts +1 -2
- package/dist/client.js +1 -2
- package/dist/codegen/datasource-types.js +1 -1
- package/dist/core/file-upload.d.ts +2 -7
- package/dist/core/file-upload.js +1 -6
- package/dist/core/use-file-upload.d.ts +2 -2
- package/dist/index.d.ts +2 -3
- package/dist/index.js +2 -2
- package/dist/mcp.d.ts +2 -2
- package/dist/package.js +1 -1
- package/dist/server.d.ts +1 -2
- package/dist/server.js +1 -2
- package/package.json +1 -3
- package/skills/softr-sdk/SKILL.md +7 -7
- package/skills/softr-sdk/auth/SKILL.md +1 -1
- package/skills/softr-sdk/charts-and-metrics/SKILL.md +1 -1
- package/skills/softr-sdk/current-user/SKILL.md +1 -1
- package/skills/softr-sdk/file-uploads/SKILL.md +4 -5
- package/skills/softr-sdk/integrations/SKILL.md +1 -1
- package/skills/softr-sdk/mcp/SKILL.md +1 -1
- package/skills/softr-sdk/pwa/SKILL.md +1 -1
- package/skills/softr-sdk/record-mutations/SKILL.md +1 -1
- package/skills/softr-sdk/record-queries/SKILL.md +2 -2
- package/skills/softr-sdk/record-queries/references/field-types.md +1 -1
- package/skills/softr-sdk/region-visibility/SKILL.md +1 -1
- package/skills/softr-sdk/routes-and-visibility/SKILL.md +1 -1
- package/skills/softr-sdk/workflows/SKILL.md +1 -1
- package/dist/comments/comments.d.ts +0 -168
- package/dist/comments/comments.js +0 -413
- package/dist/comments/use-comment-composer.d.ts +0 -46
- package/dist/comments/use-comment-composer.js +0 -134
- package/skills/softr-sdk/comments/SKILL.md +0 -180
package/dist/action.d.ts
CHANGED
|
@@ -234,35 +234,5 @@ type IntegrationDefinition<TId extends string> = {
|
|
|
234
234
|
* const res = await listEvents({ query: { timeMin: now, singleEvents: "true" } })
|
|
235
235
|
*/
|
|
236
236
|
declare function defineIntegration<const TId extends string>(definition: IntegrationDefinition<TId>): IntegrationAction<TId>;
|
|
237
|
-
type CommentsResource = {
|
|
238
|
-
type: "COMMENTS";
|
|
239
|
-
datasourceId: SoftrDatasourceId;
|
|
240
|
-
};
|
|
241
|
-
/** Comment threads on the records of one datasource. It has no `permissions`. */
|
|
242
|
-
type CommentsAction<TId extends string = string> = {
|
|
243
|
-
id: TId;
|
|
244
|
-
resource: CommentsResource;
|
|
245
|
-
};
|
|
246
|
-
type CommentsDefinition<TId extends string> = {
|
|
247
|
-
id: TId;
|
|
248
|
-
datasourceId: SoftrDatasourceId;
|
|
249
|
-
};
|
|
250
|
-
/**
|
|
251
|
-
* Declares comment threads on the records of a datasource. Each record has one thread.
|
|
252
|
-
*
|
|
253
|
-
* Who may read, post and delete comes from the app's comment settings in Softr, not from code. Two
|
|
254
|
-
* declarations on the same datasource share the same threads.
|
|
255
|
-
*
|
|
256
|
-
* Pass the returned object to `comments.*` from `@softr/sdk/server`.
|
|
257
|
-
*
|
|
258
|
-
* @example
|
|
259
|
-
* const orderComments = defineComments({
|
|
260
|
-
* id: "orderComments",
|
|
261
|
-
* datasourceId: "8f14e45f-ceea-467a-9d0b-2c1a0e3b5d77",
|
|
262
|
-
* })
|
|
263
|
-
*
|
|
264
|
-
* const thread = await comments.list(orderComments, { recordId })
|
|
265
|
-
*/
|
|
266
|
-
declare function defineComments<const TId extends string>(definition: CommentsDefinition<TId>): CommentsAction<TId>;
|
|
267
237
|
//#endregion
|
|
268
|
-
export { ActionData, ActionPermissions, ActionRecord, ActionShape,
|
|
238
|
+
export { ActionData, ActionPermissions, ActionRecord, ActionShape, DatasourceAction, FieldTypeOf, IntegrationAction, ReadOf, ReadShape, SoftrDatasources, WorkflowAction, defineIntegration, defineMutation, defineQuery, defineWorkflow };
|
package/dist/action.js
CHANGED
|
@@ -50,31 +50,6 @@ function defineIntegration(definition) {
|
|
|
50
50
|
permissions
|
|
51
51
|
};
|
|
52
52
|
}
|
|
53
|
-
/**
|
|
54
|
-
* Declares comment threads on the records of a datasource. Each record has one thread.
|
|
55
|
-
*
|
|
56
|
-
* Who may read, post and delete comes from the app's comment settings in Softr, not from code. Two
|
|
57
|
-
* declarations on the same datasource share the same threads.
|
|
58
|
-
*
|
|
59
|
-
* Pass the returned object to `comments.*` from `@softr/sdk/server`.
|
|
60
|
-
*
|
|
61
|
-
* @example
|
|
62
|
-
* const orderComments = defineComments({
|
|
63
|
-
* id: "orderComments",
|
|
64
|
-
* datasourceId: "8f14e45f-ceea-467a-9d0b-2c1a0e3b5d77",
|
|
65
|
-
* })
|
|
66
|
-
*
|
|
67
|
-
* const thread = await comments.list(orderComments, { recordId })
|
|
68
|
-
*/
|
|
69
|
-
function defineComments(definition) {
|
|
70
|
-
return {
|
|
71
|
-
id: definition.id,
|
|
72
|
-
resource: {
|
|
73
|
-
type: "COMMENTS",
|
|
74
|
-
datasourceId: definition.datasourceId
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
53
|
function isDatasourceAction(value) {
|
|
79
54
|
if (typeof value !== "object" || value === null) return false;
|
|
80
55
|
const candidate = value;
|
|
@@ -83,4 +58,4 @@ function isDatasourceAction(value) {
|
|
|
83
58
|
}
|
|
84
59
|
|
|
85
60
|
//#endregion
|
|
86
|
-
export {
|
|
61
|
+
export { defineIntegration, defineMutation, defineQuery, defineWorkflow, isDatasourceAction };
|
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
import { FileItem, useFileUpload } from "./core/use-file-upload.js";
|
|
2
|
-
import { useCommentComposer } from "./comments/use-comment-composer.js";
|
|
3
2
|
import "@tanstack/react-start/client-only";
|
|
4
|
-
export { type FileItem,
|
|
3
|
+
export { type FileItem, useFileUpload };
|
package/dist/client.js
CHANGED
|
@@ -422,7 +422,7 @@ function scalarExample(shape) {
|
|
|
422
422
|
case "PROGRESS":
|
|
423
423
|
case "COUNT":
|
|
424
424
|
case "AUTONUMBER": return String(numberExample(shape.options));
|
|
425
|
-
case "DURATION": return "
|
|
425
|
+
case "DURATION": return "3600000";
|
|
426
426
|
case "RATING": {
|
|
427
427
|
const max = option(shape.options, "max");
|
|
428
428
|
return String(typeof max === "number" ? max : 5);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DatasourceAction } from "../action.js";
|
|
2
2
|
|
|
3
3
|
//#region src/core/file-upload.d.ts
|
|
4
4
|
|
|
@@ -10,12 +10,7 @@ type FileAttachment = {
|
|
|
10
10
|
url: string;
|
|
11
11
|
filename: string;
|
|
12
12
|
id: string;
|
|
13
|
-
type?: string | null;
|
|
14
13
|
};
|
|
15
|
-
|
|
16
|
-
* A COMMENTS action uploads a comment attachment.
|
|
17
|
-
* The platform checks the comment settings.
|
|
18
|
-
*/
|
|
19
|
-
declare function upload(action: DatasourceAction | CommentsAction, file: File): Promise<FileAttachment>;
|
|
14
|
+
declare function upload(action: DatasourceAction, file: File): Promise<FileAttachment>;
|
|
20
15
|
//#endregion
|
|
21
16
|
export { FileAttachment, upload };
|
package/dist/core/file-upload.js
CHANGED
|
@@ -5,10 +5,6 @@ import { platformApiUrl } from "../auth/platform.js";
|
|
|
5
5
|
import { randomUUID } from "node:crypto";
|
|
6
6
|
|
|
7
7
|
//#region src/core/file-upload.ts
|
|
8
|
-
/**
|
|
9
|
-
* A COMMENTS action uploads a comment attachment.
|
|
10
|
-
* The platform checks the comment settings.
|
|
11
|
-
*/
|
|
12
8
|
async function upload(action, file) {
|
|
13
9
|
const { applicationId } = sessionConfig();
|
|
14
10
|
const baseUrl = await platformApiUrl();
|
|
@@ -27,8 +23,7 @@ async function upload(action, file) {
|
|
|
27
23
|
return {
|
|
28
24
|
url: resultJSON.url,
|
|
29
25
|
filename: resultJSON.filename || "Untitled file",
|
|
30
|
-
id: resultJSON.id || randomUUID()
|
|
31
|
-
type: resultJSON.type ?? null
|
|
26
|
+
id: resultJSON.id || randomUUID()
|
|
32
27
|
};
|
|
33
28
|
}
|
|
34
29
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DatasourceAction } from "../action.js";
|
|
2
2
|
import { FileAttachment } from "./file-upload.js";
|
|
3
3
|
|
|
4
4
|
//#region src/core/use-file-upload.d.ts
|
|
@@ -16,7 +16,7 @@ type FileItem = {
|
|
|
16
16
|
filename: string;
|
|
17
17
|
error: Error;
|
|
18
18
|
};
|
|
19
|
-
declare function useFileUpload(action: DatasourceAction
|
|
19
|
+
declare function useFileUpload(action: DatasourceAction, options?: {
|
|
20
20
|
initialAttachments?: FileAttachment[];
|
|
21
21
|
}): {
|
|
22
22
|
files: FileItem[];
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { SoftrUserGroupId, SoftrUserGroups, User } from "./auth/user.js";
|
|
2
|
-
import { ActionPermissions, SoftrDatasources,
|
|
2
|
+
import { ActionPermissions, SoftrDatasources, defineIntegration, defineMutation, defineQuery, defineWorkflow } from "./action.js";
|
|
3
3
|
import { FileAttachment } from "./core/file-upload.js";
|
|
4
4
|
import { FileItem, useFileUpload } from "./core/use-file-upload.js";
|
|
5
|
-
import { CommentAttachmentInput, CommentMention, CommentThread, CommentView } from "./comments/comments.js";
|
|
6
5
|
import { SoftrContext } from "./auth/context.js";
|
|
7
6
|
import { checkAccess, defineVisibility, isAuthorized } from "./visibility/visibility.js";
|
|
8
7
|
import { assertRouteAccess, guardRoute, isAccessError, isAlreadyAuthenticatedError, isForbiddenError, isUnauthenticatedError } from "./visibility/route.js";
|
|
@@ -12,4 +11,4 @@ import { useUserTimezone } from "./timezone.js";
|
|
|
12
11
|
import { PwaInstall, PwaPlatform, SoftrPwaHead, usePwaInstall } from "./pwa.js";
|
|
13
12
|
import { DefaultErrorOverlay } from "./default-error-overlay.js";
|
|
14
13
|
import { Audience } from "./visibility/audience.js";
|
|
15
|
-
export { type ActionPermissions, Audience,
|
|
14
|
+
export { type ActionPermissions, Audience, DefaultErrorOverlay, type FileAttachment, type FileItem, type PwaInstall, type PwaPlatform, type SoftrContext, type SoftrDatasources, SoftrPwaHead, type SoftrUserGroupId, type SoftrUserGroups, type User, assertRouteAccess, checkAccess, defineIntegration, defineMutation, defineQuery, defineVisibility, defineWorkflow, getSoftrContext, guardRoute, initialSoftrContext, isAccessError, isAlreadyAuthenticatedError, isAuthorized, isForbiddenError, isUnauthenticatedError, softrAuthMiddleware, softrMcpMiddleware, useCurrentUser, useFileUpload, usePwaInstall, useUserTimezone };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useFileUpload } from "./core/use-file-upload.js";
|
|
2
|
-
import {
|
|
2
|
+
import { defineIntegration, defineMutation, defineQuery, defineWorkflow } from "./action.js";
|
|
3
3
|
import { checkAccess, defineVisibility, isAuthorized } from "./visibility/visibility.js";
|
|
4
4
|
import { assertRouteAccess, guardRoute, isAccessError, isAlreadyAuthenticatedError, isForbiddenError, isUnauthenticatedError } from "./visibility/route.js";
|
|
5
5
|
import { SoftrPwaHead, usePwaInstall } from "./pwa.js";
|
|
@@ -9,4 +9,4 @@ import { useUserTimezone } from "./timezone.js";
|
|
|
9
9
|
import { DefaultErrorOverlay } from "./default-error-overlay.js";
|
|
10
10
|
import { Audience } from "./visibility/audience.js";
|
|
11
11
|
|
|
12
|
-
export { Audience, DefaultErrorOverlay, SoftrPwaHead, assertRouteAccess, checkAccess,
|
|
12
|
+
export { Audience, DefaultErrorOverlay, SoftrPwaHead, assertRouteAccess, checkAccess, defineIntegration, defineMutation, defineQuery, defineVisibility, defineWorkflow, getSoftrContext, guardRoute, initialSoftrContext, isAccessError, isAlreadyAuthenticatedError, isAuthorized, isForbiddenError, isUnauthenticatedError, softrAuthMiddleware, softrMcpMiddleware, useCurrentUser, useFileUpload, usePwaInstall, useUserTimezone };
|
package/dist/mcp.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DatasourceAction } from "./action.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as _tanstack_react_start3 from "@tanstack/react-start";
|
|
3
3
|
|
|
4
4
|
//#region src/mcp.d.ts
|
|
5
5
|
|
|
@@ -37,6 +37,6 @@ type SoftrMcpOptions = {
|
|
|
37
37
|
* ],
|
|
38
38
|
* }))
|
|
39
39
|
*/
|
|
40
|
-
declare function softrMcpMiddleware(options?: SoftrMcpOptions):
|
|
40
|
+
declare function softrMcpMiddleware(options?: SoftrMcpOptions): _tanstack_react_start3.RequestMiddlewareAfterServer<{}, undefined, undefined>;
|
|
41
41
|
//#endregion
|
|
42
42
|
export { softrMcpMiddleware };
|
package/dist/package.js
CHANGED
package/dist/server.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { upload } from "./core/file-upload.js";
|
|
2
|
-
import { comments } from "./comments/comments.js";
|
|
3
2
|
import { auth } from "./auth/server.js";
|
|
4
3
|
import { ds } from "./datasource/datasource.js";
|
|
5
4
|
import { workflow } from "./core/workflow.js";
|
|
6
5
|
import { integration } from "./core/integration.js";
|
|
7
6
|
import "@tanstack/react-start/server-only";
|
|
8
|
-
export { auth,
|
|
7
|
+
export { auth, ds, integration, upload, workflow };
|
package/dist/server.js
CHANGED
|
@@ -3,7 +3,6 @@ import { ds } from "./datasource/datasource.js";
|
|
|
3
3
|
import { auth } from "./auth/server.js";
|
|
4
4
|
import { workflow } from "./core/workflow.js";
|
|
5
5
|
import { integration } from "./core/integration.js";
|
|
6
|
-
import { comments } from "./comments/comments.js";
|
|
7
6
|
import "@tanstack/react-start/server-only";
|
|
8
7
|
|
|
9
|
-
export { auth,
|
|
8
|
+
export { auth, ds, integration, upload, workflow };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@softr/sdk",
|
|
3
|
-
"version": "0.0.56-alpha.
|
|
3
|
+
"version": "0.0.56-alpha.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" },
|
|
@@ -17,8 +17,6 @@
|
|
|
17
17
|
"typecheck": "tsc --noEmit"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"marked": "^18.0.14",
|
|
21
|
-
"xss": "^1.0.15",
|
|
22
20
|
"zod": "^4.4.3"
|
|
23
21
|
},
|
|
24
22
|
"devDependencies": {
|
|
@@ -11,7 +11,7 @@ description: >-
|
|
|
11
11
|
metadata:
|
|
12
12
|
type: core
|
|
13
13
|
library: softr-sdk
|
|
14
|
-
library_version: 0.0.
|
|
14
|
+
library_version: 0.0.55
|
|
15
15
|
---
|
|
16
16
|
|
|
17
17
|
# Softr SDK core
|
|
@@ -29,9 +29,9 @@ Each sub-skill stands alone for its task and repeats the boundary above, so most
|
|
|
29
29
|
|
|
30
30
|
| Import | Runs | Holds |
|
|
31
31
|
| --- | --- | --- |
|
|
32
|
-
| `@softr/sdk` | Both | `defineQuery`, `defineMutation`, `
|
|
33
|
-
| `@softr/sdk/server` | Server only | `ds`, `auth`, `workflow`, `integration
|
|
34
|
-
| `@softr/sdk/client` | Browser only |
|
|
32
|
+
| `@softr/sdk` | Both | `defineQuery`, `defineMutation`, `defineVisibility`, `guardRoute`, `assertRouteAccess`, `isAuthorized`, `checkAccess`, `Audience`, `useCurrentUser`, `useUserTimezone`, `SoftrPwaHead`, `usePwaInstall`, `getSoftrContext`, `initialSoftrContext`, `softrAuthMiddleware`, the error predicates, and every type |
|
|
33
|
+
| `@softr/sdk/server` | Server only | `ds`, `auth`, `workflow`, `integration` |
|
|
34
|
+
| `@softr/sdk/client` | Browser only | Nothing yet, reserved for browser-only utilities |
|
|
35
35
|
| `@softr/sdk/vite` | Build | `softr()`, already in `vite.config.ts` |
|
|
36
36
|
|
|
37
37
|
## Sub-Skills
|
|
@@ -48,7 +48,7 @@ Each sub-skill stands alone for its task and repeats the boundary above, so most
|
|
|
48
48
|
| Sign a visitor in, out, or up | [auth/SKILL.md](./auth/SKILL.md) |
|
|
49
49
|
| Call a connected third-party API (Slack, Stripe, Gmail, …) | [integrations/SKILL.md](./integrations/SKILL.md) |
|
|
50
50
|
| Open the app to AI assistants over MCP | [mcp/SKILL.md](./mcp/SKILL.md) |
|
|
51
|
-
|
|
|
51
|
+
| Let visitors install the app on their home screen | [pwa/SKILL.md](./pwa/SKILL.md) |
|
|
52
52
|
|
|
53
53
|
## Quick Decision Tree
|
|
54
54
|
|
|
@@ -83,8 +83,8 @@ Calling a connected third-party API (Slack, Stripe, Gmail, Google Calendar, …)
|
|
|
83
83
|
Opening the app to an AI assistant over MCP?
|
|
84
84
|
load softr-sdk/mcp
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
load softr-sdk/
|
|
86
|
+
Adding an install button, or making the app installable?
|
|
87
|
+
load softr-sdk/pwa
|
|
88
88
|
|
|
89
89
|
Writing a server function, loader, or middleware in general?
|
|
90
90
|
not a Softr concern. Use the TanStack Start skills.
|
|
@@ -16,7 +16,7 @@ description: >-
|
|
|
16
16
|
metadata:
|
|
17
17
|
type: sub-skill
|
|
18
18
|
library: softr-sdk
|
|
19
|
-
library_version: 0.0.
|
|
19
|
+
library_version: 0.0.55
|
|
20
20
|
---
|
|
21
21
|
|
|
22
22
|
**Boundary.** `auth` lives on `@softr/sdk/server` and runs only inside a `createServerFn` handler — importing it into a component fails the build.
|
|
@@ -12,7 +12,7 @@ description: >-
|
|
|
12
12
|
metadata:
|
|
13
13
|
type: sub-skill
|
|
14
14
|
library: softr-sdk
|
|
15
|
-
library_version: 0.0.
|
|
15
|
+
library_version: 0.0.55
|
|
16
16
|
---
|
|
17
17
|
|
|
18
18
|
**Boundary.** `ds` lives on `@softr/sdk/server` and runs only inside a `createServerFn` handler or a server-side route hook — importing it into a component fails the build. `defineQuery` and every type come from `@softr/sdk` and can be imported anywhere.
|
|
@@ -10,7 +10,7 @@ description: >-
|
|
|
10
10
|
metadata:
|
|
11
11
|
type: sub-skill
|
|
12
12
|
library: softr-sdk
|
|
13
|
-
library_version: 0.0.
|
|
13
|
+
library_version: 0.0.55
|
|
14
14
|
---
|
|
15
15
|
|
|
16
16
|
**Boundary.** `upload` lives on `@softr/sdk/server` and runs inside server functions. `useFileUpload` and `FileItem` live on `@softr/sdk` and run in components. `FileAttachment` comes from `@softr/sdk` and can be imported anywhere.
|
|
@@ -75,10 +75,9 @@ function ApplicationForm() {
|
|
|
75
75
|
|
|
76
76
|
```ts
|
|
77
77
|
type FileAttachment = {
|
|
78
|
-
url: string
|
|
79
|
-
filename: string
|
|
80
|
-
id: string
|
|
81
|
-
type?: string | null // content type from the upload response, or null when the platform doesn't know it
|
|
78
|
+
url: string // clean URL, no internal query params
|
|
79
|
+
filename: string // original filename
|
|
80
|
+
id: string // file id extracted from the upload response
|
|
82
81
|
}
|
|
83
82
|
```
|
|
84
83
|
|
|
@@ -10,7 +10,7 @@ description: >-
|
|
|
10
10
|
metadata:
|
|
11
11
|
type: sub-skill
|
|
12
12
|
library: softr-sdk
|
|
13
|
-
library_version: 0.0.
|
|
13
|
+
library_version: 0.0.55
|
|
14
14
|
---
|
|
15
15
|
|
|
16
16
|
**Boundary.** `integration` lives on `@softr/sdk/server` and runs only inside a `createServerFn` handler — importing it into a component fails the build. `defineIntegration` and every type come from `@softr/sdk` and can be imported anywhere.
|
|
@@ -9,7 +9,7 @@ description: >-
|
|
|
9
9
|
metadata:
|
|
10
10
|
type: sub-skill
|
|
11
11
|
library: softr-sdk
|
|
12
|
-
library_version: 0.0.
|
|
12
|
+
library_version: 0.0.55
|
|
13
13
|
---
|
|
14
14
|
|
|
15
15
|
**Boundary.** `softrMcpMiddleware` lives on `@softr/sdk` and is registered once, in `src/start.ts`. The actions you hand it are the same `defineQuery` / `defineMutation` values the app's own pages use — declared wherever they already live, not duplicated for MCP.
|
|
@@ -11,7 +11,7 @@ description: >-
|
|
|
11
11
|
metadata:
|
|
12
12
|
type: sub-skill
|
|
13
13
|
library: softr-sdk
|
|
14
|
-
library_version: 0.0.
|
|
14
|
+
library_version: 0.0.55
|
|
15
15
|
---
|
|
16
16
|
|
|
17
17
|
**Boundary.** `ds` lives on `@softr/sdk/server` and runs only inside a `createServerFn` handler — importing it into a component fails the build. `defineMutation` and every type come from `@softr/sdk` and can be imported anywhere.
|
|
@@ -13,10 +13,10 @@ description: >-
|
|
|
13
13
|
metadata:
|
|
14
14
|
type: sub-skill
|
|
15
15
|
library: softr-sdk
|
|
16
|
-
library_version: 0.0.
|
|
16
|
+
library_version: 0.0.55
|
|
17
17
|
---
|
|
18
18
|
|
|
19
|
-
**Boundary.** `ds` lives on `@softr/sdk/server` and runs only inside a `createServerFn` handler or a server-side route hook — importing it into a component fails the build. `defineQuery` and every type come from `@softr/sdk` and can be imported anywhere.
|
|
19
|
+
**Boundary.** `ds` lives on `@softr/sdk/server` and runs only inside a `createServerFn` handler or a server-side route hook — importing it into a component fails the build. The same holds for any helper that calls `ds`: declare it inside the handler. A function at module level that calls `ds` keeps the server-only import in the browser bundle, and every page stops loading until it moves. `defineQuery` and every type come from `@softr/sdk` and can be imported anywhere.
|
|
20
20
|
|
|
21
21
|
# Reading records
|
|
22
22
|
|
|
@@ -56,7 +56,7 @@ Every scalar above is `| null` on the record unless the field allows multiple en
|
|
|
56
56
|
<td>{record.fields.status}</td>
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
-
**DURATION** is
|
|
59
|
+
**DURATION** is milliseconds, whatever format the field displays in: `3600000` is one hour.
|
|
60
60
|
|
|
61
61
|
**DATETIME at date precision** is generated as a `DATE` field and holds `'2026-03-14'`, not a timestamp.
|
|
62
62
|
|
|
@@ -13,7 +13,7 @@ description: >-
|
|
|
13
13
|
metadata:
|
|
14
14
|
type: sub-skill
|
|
15
15
|
library: softr-sdk
|
|
16
|
-
library_version: 0.0.
|
|
16
|
+
library_version: 0.0.55
|
|
17
17
|
---
|
|
18
18
|
|
|
19
19
|
**Boundary.** `defineVisibility`, the access functions and the error predicates come from `@softr/sdk` and work anywhere.
|
|
@@ -9,7 +9,7 @@ description: >-
|
|
|
9
9
|
metadata:
|
|
10
10
|
type: sub-skill
|
|
11
11
|
library: softr-sdk
|
|
12
|
-
library_version: 0.0.
|
|
12
|
+
library_version: 0.0.55
|
|
13
13
|
---
|
|
14
14
|
|
|
15
15
|
**Boundary.** `workflow` lives on `@softr/sdk/server` and runs only inside a `createServerFn` handler — importing it into a component fails the build. `defineWorkflow` and every type come from `@softr/sdk` and can be imported anywhere.
|
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
import { CommentsAction } from "../action.js";
|
|
2
|
-
|
|
3
|
-
//#region src/comments/comments.d.ts
|
|
4
|
-
/** A person picked in the composer, and where their `@name` sits in the text. */
|
|
5
|
-
type CommentMention = {
|
|
6
|
-
name: string;
|
|
7
|
-
email: string;
|
|
8
|
-
start: number;
|
|
9
|
-
end: number;
|
|
10
|
-
};
|
|
11
|
-
type CommentAttachmentInput = {
|
|
12
|
-
url: string;
|
|
13
|
-
filename: string;
|
|
14
|
-
type?: string | null;
|
|
15
|
-
};
|
|
16
|
-
type CommentView = {
|
|
17
|
-
id: string;
|
|
18
|
-
/** The body as safe HTML. Render it with `dangerouslySetInnerHTML`, never as text. */
|
|
19
|
-
bodyHtml: string;
|
|
20
|
-
attachments: Array<{
|
|
21
|
-
url: string;
|
|
22
|
-
filename: string;
|
|
23
|
-
type: string | null;
|
|
24
|
-
}>;
|
|
25
|
-
author: {
|
|
26
|
-
name: string;
|
|
27
|
-
avatar: string | null;
|
|
28
|
-
isDeactivated: boolean;
|
|
29
|
-
};
|
|
30
|
-
/** ISO 8601. */
|
|
31
|
-
createdAt: string;
|
|
32
|
-
canDelete: boolean;
|
|
33
|
-
canEdit: boolean;
|
|
34
|
-
edited: boolean;
|
|
35
|
-
/** The body as the visitor typed it, to fill an edit box. `null` unless `canEdit`. */
|
|
36
|
-
source: {
|
|
37
|
-
text: string;
|
|
38
|
-
mentions: Array<CommentMention>;
|
|
39
|
-
} | null;
|
|
40
|
-
reactions: Array<{
|
|
41
|
-
emoji: string;
|
|
42
|
-
label: string;
|
|
43
|
-
count: number;
|
|
44
|
-
isSelected: boolean;
|
|
45
|
-
}>;
|
|
46
|
-
};
|
|
47
|
-
type CommentThread = {
|
|
48
|
-
canPost: boolean;
|
|
49
|
-
allowMentions: boolean;
|
|
50
|
-
allowAttachments: boolean;
|
|
51
|
-
notificationsEnabled: boolean;
|
|
52
|
-
quickReactions: ReadonlyArray<{
|
|
53
|
-
emoji: string;
|
|
54
|
-
label: string;
|
|
55
|
-
}>;
|
|
56
|
-
total: number;
|
|
57
|
-
/** Pass it back as `offset` for the next page. `null` on the last page. */
|
|
58
|
-
nextOffset: number | null;
|
|
59
|
-
items: Array<CommentView>;
|
|
60
|
-
};
|
|
61
|
-
/**
|
|
62
|
-
* The thread on one record, or `null` when this visitor cannot see comments on it. Render nothing
|
|
63
|
-
* for `null`.
|
|
64
|
-
*
|
|
65
|
-
* @example
|
|
66
|
-
* const thread = await comments.list(orderComments, { recordId: order.id })
|
|
67
|
-
*/
|
|
68
|
-
declare function listComments(action: CommentsAction, options: {
|
|
69
|
-
recordId: string;
|
|
70
|
-
offset?: number | null;
|
|
71
|
-
limit?: number;
|
|
72
|
-
}): Promise<CommentThread | null>;
|
|
73
|
-
/**
|
|
74
|
-
* Posts a comment. `body` is the text the visitor typed. `mentions` are the people they picked,
|
|
75
|
-
* each with the range of its `@name` in `body`. A range that no longer reads as `@name` is posted as
|
|
76
|
-
* plain text. `attachments` are the files `useFileUpload` finished uploading.
|
|
77
|
-
*
|
|
78
|
-
* @example
|
|
79
|
-
* await comments.create(orderComments, { recordId, body: "Hey @Ann", mentions, attachments })
|
|
80
|
-
*/
|
|
81
|
-
declare function createComment(action: CommentsAction, options: {
|
|
82
|
-
recordId: string;
|
|
83
|
-
body: string;
|
|
84
|
-
mentions: ReadonlyArray<CommentMention>;
|
|
85
|
-
attachments?: ReadonlyArray<CommentAttachmentInput>;
|
|
86
|
-
}): Promise<void>;
|
|
87
|
-
/**
|
|
88
|
-
* Saves an edit. Offer it only where the comment's `canEdit` is true, and fill the edit box from its
|
|
89
|
-
* `source`. `attachments` is the full list after the edit: the files kept plus any new ones.
|
|
90
|
-
*
|
|
91
|
-
* @example
|
|
92
|
-
* await comments.update(orderComments, { recordId, commentId, body, mentions, attachments })
|
|
93
|
-
*/
|
|
94
|
-
declare function updateComment(action: CommentsAction, options: {
|
|
95
|
-
recordId: string;
|
|
96
|
-
commentId: string;
|
|
97
|
-
body: string;
|
|
98
|
-
mentions: ReadonlyArray<CommentMention>;
|
|
99
|
-
attachments: ReadonlyArray<CommentAttachmentInput>;
|
|
100
|
-
}): Promise<void>;
|
|
101
|
-
/**
|
|
102
|
-
* Deletes a comment. Offer it only where the comment's `canDelete` is true.
|
|
103
|
-
*
|
|
104
|
-
* @example
|
|
105
|
-
* await comments.delete(orderComments, { recordId, commentId })
|
|
106
|
-
*/
|
|
107
|
-
declare function deleteComment(action: CommentsAction, options: {
|
|
108
|
-
recordId: string;
|
|
109
|
-
commentId: string;
|
|
110
|
-
}): Promise<void>;
|
|
111
|
-
/**
|
|
112
|
-
* Adds the visitor's reaction when `selected` is true, and removes it when false. Pass the
|
|
113
|
-
* reaction's current `isSelected` negated.
|
|
114
|
-
*
|
|
115
|
-
* @example
|
|
116
|
-
* await comments.react(orderComments, { recordId, commentId, emoji: "👍", selected: true })
|
|
117
|
-
*/
|
|
118
|
-
declare function reactToComment(action: CommentsAction, options: {
|
|
119
|
-
recordId: string;
|
|
120
|
-
commentId: string;
|
|
121
|
-
emoji: string;
|
|
122
|
-
selected: boolean;
|
|
123
|
-
}): Promise<void>;
|
|
124
|
-
/**
|
|
125
|
-
* Whether the visitor gets an email when someone comments on this record.
|
|
126
|
-
*
|
|
127
|
-
* @example
|
|
128
|
-
* const subscribed = await comments.subscription(orderComments, { recordId })
|
|
129
|
-
*/
|
|
130
|
-
declare function readSubscription(action: CommentsAction, options: {
|
|
131
|
-
recordId: string;
|
|
132
|
-
}): Promise<boolean>;
|
|
133
|
-
/**
|
|
134
|
-
* Turns the visitor's emails about this record's comments on or off.
|
|
135
|
-
*
|
|
136
|
-
* @example
|
|
137
|
-
* await comments.setSubscription(orderComments, { recordId, subscribed: false })
|
|
138
|
-
*/
|
|
139
|
-
declare function setSubscription(action: CommentsAction, options: {
|
|
140
|
-
recordId: string;
|
|
141
|
-
subscribed: boolean;
|
|
142
|
-
}): Promise<void>;
|
|
143
|
-
/**
|
|
144
|
-
* The people the visitor may mention whose name or email matches `query`. Only call it when the
|
|
145
|
-
* thread's `allowMentions` is true.
|
|
146
|
-
*
|
|
147
|
-
* @example
|
|
148
|
-
* const people = await comments.searchMentions(orderComments, { query: "an" })
|
|
149
|
-
*/
|
|
150
|
-
declare function searchMentions(action: CommentsAction, options: {
|
|
151
|
-
query: string;
|
|
152
|
-
}): Promise<Array<{
|
|
153
|
-
name: string;
|
|
154
|
-
email: string;
|
|
155
|
-
avatar: string | null;
|
|
156
|
-
}>>;
|
|
157
|
-
declare const comments: {
|
|
158
|
-
list: typeof listComments;
|
|
159
|
-
create: typeof createComment;
|
|
160
|
-
update: typeof updateComment;
|
|
161
|
-
delete: typeof deleteComment;
|
|
162
|
-
react: typeof reactToComment;
|
|
163
|
-
subscription: typeof readSubscription;
|
|
164
|
-
setSubscription: typeof setSubscription;
|
|
165
|
-
searchMentions: typeof searchMentions;
|
|
166
|
-
};
|
|
167
|
-
//#endregion
|
|
168
|
-
export { CommentAttachmentInput, CommentMention, CommentThread, CommentView, comments };
|