@softr/sdk 0.0.63-alpha.0 → 0.0.63

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 (35) hide show
  1. package/dist/action.d.ts +1 -31
  2. package/dist/action.js +1 -26
  3. package/dist/client.d.ts +1 -2
  4. package/dist/client.js +1 -2
  5. package/dist/core/file-upload.d.ts +2 -7
  6. package/dist/core/file-upload.js +1 -6
  7. package/dist/core/use-file-upload.d.ts +2 -2
  8. package/dist/datasource/record.js +11 -5
  9. package/dist/formatting.d.ts +3 -3
  10. package/dist/index.d.ts +2 -3
  11. package/dist/index.js +2 -2
  12. package/dist/package.js +1 -1
  13. package/dist/pwa.d.ts +2 -2
  14. package/dist/server.d.ts +1 -2
  15. package/dist/server.js +1 -2
  16. package/package.json +1 -3
  17. package/skills/softr-sdk/SKILL.md +4 -8
  18. package/skills/softr-sdk/auth/SKILL.md +1 -1
  19. package/skills/softr-sdk/charts-and-metrics/SKILL.md +1 -1
  20. package/skills/softr-sdk/current-user/SKILL.md +1 -1
  21. package/skills/softr-sdk/file-uploads/SKILL.md +4 -5
  22. package/skills/softr-sdk/formatting/SKILL.md +1 -1
  23. package/skills/softr-sdk/integrations/SKILL.md +1 -1
  24. package/skills/softr-sdk/mcp/SKILL.md +1 -1
  25. package/skills/softr-sdk/pwa/SKILL.md +1 -1
  26. package/skills/softr-sdk/record-mutations/SKILL.md +1 -1
  27. package/skills/softr-sdk/record-queries/SKILL.md +1 -1
  28. package/skills/softr-sdk/region-visibility/SKILL.md +1 -1
  29. package/skills/softr-sdk/routes-and-visibility/SKILL.md +1 -1
  30. package/skills/softr-sdk/workflows/SKILL.md +1 -1
  31. package/dist/comments/comments.d.ts +0 -168
  32. package/dist/comments/comments.js +0 -413
  33. package/dist/comments/use-comment-composer.d.ts +0 -46
  34. package/dist/comments/use-comment-composer.js +0 -134
  35. package/skills/softr-sdk/comments/SKILL.md +0 -181
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, CommentsAction, DatasourceAction, FieldTypeOf, IntegrationAction, ReadOf, ReadShape, SoftrDatasources, WorkflowAction, defineComments, defineIntegration, defineMutation, defineQuery, defineWorkflow };
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 { defineComments, defineIntegration, defineMutation, defineQuery, defineWorkflow, isDatasourceAction };
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, useCommentComposer, useFileUpload };
3
+ export { type FileItem, useFileUpload };
package/dist/client.js CHANGED
@@ -1,5 +1,4 @@
1
1
  import { 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
3
 
5
- export { useCommentComposer, useFileUpload };
4
+ export { useFileUpload };
@@ -1,4 +1,4 @@
1
- import { CommentsAction, DatasourceAction } from "../action.js";
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 };
@@ -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 { CommentsAction, DatasourceAction } from "../action.js";
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 | CommentsAction, options?: {
19
+ declare function useFileUpload(action: DatasourceAction, options?: {
20
20
  initialAttachments?: FileAttachment[];
21
21
  }): {
22
22
  files: FileItem[];
@@ -5,7 +5,7 @@ import { readSessionToken } from "../auth/session.js";
5
5
  import { isDatasourceAction } from "../action.js";
6
6
  import { buildFilterCriteria, buildOrderBy, dealiasFilterCriteria, dealiasOrderBy } from "./filter.js";
7
7
  import { andAll, makeFieldSet, makeSortSet } from "./fields.js";
8
- import { getRequestHeader } from "@tanstack/react-start/server";
8
+ import { getRequestHeader, getRequestUrl } from "@tanstack/react-start/server";
9
9
 
10
10
  //#region src/datasource/record.ts
11
11
  const MAX_RECORD_COUNT = 100;
@@ -17,13 +17,19 @@ const dsUrl = (actionId) => {
17
17
  return `${withoutTrailingSlash(datasourceApiUrl)}/v1/datasource/vibe/applications/${applicationId}/actions/${actionId}`;
18
18
  };
19
19
  /**
20
- * The datasource API wants to know which page made the call.
21
- * The browser sends that page to the app server, so we pass it on.
22
- * Without an incoming Referer, we send none.
20
+ * The datasource API wants to know which page made the call, and rejects a call without it.
21
+ *
22
+ * A call from the browser has a Referer on this app's origin, and that Referer names the page.
23
+ * A page load has the previous page as its Referer: Studio, or none for a pasted link.
24
+ * There the page is the request itself, so we send the request URL.
23
25
  */
24
26
  function refererHeader() {
27
+ const page = getRequestUrl({
28
+ xForwardedHost: true,
29
+ xForwardedProto: true
30
+ });
25
31
  const referer = getRequestHeader("referer");
26
- return referer ? { Referer: referer } : {};
32
+ return { Referer: referer !== void 0 && URL.parse(referer)?.origin === page.origin ? referer : page.href };
27
33
  }
28
34
  async function describeFailure(res) {
29
35
  const body = await res.json().catch(() => null);
@@ -1,4 +1,4 @@
1
- import * as react1 from "react";
1
+ import * as react0 from "react";
2
2
  import { ReactNode } from "react";
3
3
  import { z } from "zod";
4
4
 
@@ -94,7 +94,7 @@ declare function FormattingScope({
94
94
  /** A BCP 47 locale, such as `de-DE`. It drops the app's fixed date format inside the scope. */
95
95
  locale?: string;
96
96
  children?: ReactNode;
97
- }): react1.FunctionComponentElement<react1.ProviderProps<Scope>>;
97
+ }): react0.FunctionComponentElement<react0.ProviderProps<Scope>>;
98
98
  /**
99
99
  * A date in the app's format, safe to render on the server. A timestamp whose
100
100
  * zone is not known yet renders `fallback` until the browser supplies it, so
@@ -115,6 +115,6 @@ declare function FormattedDate({
115
115
  time?: boolean;
116
116
  /** What renders while the visitor's zone is unknown. */
117
117
  fallback?: ReactNode;
118
- }): react1.FunctionComponentElement<react1.FragmentProps>;
118
+ }): react0.FunctionComponentElement<react0.FragmentProps>;
119
119
  //#endregion
120
120
  export { DateOptions, DateParts, DateSeparator, DateValue, FixedDateFormat, FormattedDate, Formatting, FormattingScope, WeekDay, formatDate, formatDateTime, formatNumber, useFormatting };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,7 @@
1
1
  import { SoftrUserGroupId, SoftrUserGroups, User } from "./auth/user.js";
2
- import { ActionPermissions, SoftrDatasources, defineComments, defineIntegration, defineMutation, defineQuery, defineWorkflow } from "./action.js";
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 { DateOptions, DateParts, DateSeparator, DateValue, FixedDateFormat, FormattedDate, Formatting, FormattingScope, WeekDay, formatDate, formatDateTime, formatNumber, useFormatting } from "./formatting.js";
7
6
  import { SoftrContext } from "./auth/context.js";
8
7
  import { checkAccess, defineVisibility, isAuthorized } from "./visibility/visibility.js";
@@ -13,4 +12,4 @@ import { useUserTimezone } from "./timezone.js";
13
12
  import { PwaInstall, PwaPlatform, SoftrPwaHead, usePwaInstall } from "./pwa.js";
14
13
  import { DefaultErrorOverlay } from "./default-error-overlay.js";
15
14
  import { Audience } from "./visibility/audience.js";
16
- export { type ActionPermissions, Audience, type CommentAttachmentInput, type CommentMention, type CommentThread, type CommentView, type DateOptions, type DateParts, type DateSeparator, type DateValue, DefaultErrorOverlay, type FileAttachment, type FileItem, type FixedDateFormat, FormattedDate, type Formatting, FormattingScope, type PwaInstall, type PwaPlatform, type SoftrContext, type SoftrDatasources, SoftrPwaHead, type SoftrUserGroupId, type SoftrUserGroups, type User, type WeekDay, assertRouteAccess, checkAccess, defineComments, defineIntegration, defineMutation, defineQuery, defineVisibility, defineWorkflow, formatDate, formatDateTime, formatNumber, getSoftrContext, guardRoute, initialSoftrContext, isAccessError, isAlreadyAuthenticatedError, isAuthorized, isForbiddenError, isUnauthenticatedError, softrAuthMiddleware, softrMcpMiddleware, useCurrentUser, useFileUpload, useFormatting, usePwaInstall, useUserTimezone };
15
+ export { type ActionPermissions, Audience, type DateOptions, type DateParts, type DateSeparator, type DateValue, DefaultErrorOverlay, type FileAttachment, type FileItem, type FixedDateFormat, FormattedDate, type Formatting, FormattingScope, type PwaInstall, type PwaPlatform, type SoftrContext, type SoftrDatasources, SoftrPwaHead, type SoftrUserGroupId, type SoftrUserGroups, type User, type WeekDay, assertRouteAccess, checkAccess, defineIntegration, defineMutation, defineQuery, defineVisibility, defineWorkflow, formatDate, formatDateTime, formatNumber, getSoftrContext, guardRoute, initialSoftrContext, isAccessError, isAlreadyAuthenticatedError, isAuthorized, isForbiddenError, isUnauthenticatedError, softrAuthMiddleware, softrMcpMiddleware, useCurrentUser, useFileUpload, useFormatting, usePwaInstall, useUserTimezone };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { useFileUpload } from "./core/use-file-upload.js";
2
- import { defineComments, defineIntegration, defineMutation, defineQuery, defineWorkflow } from "./action.js";
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 { FormattedDate, FormattingScope, formatDate, formatDateTime, formatNumber, useFormatting } from "./formatting.js";
@@ -10,4 +10,4 @@ import { useUserTimezone } from "./timezone.js";
10
10
  import { DefaultErrorOverlay } from "./default-error-overlay.js";
11
11
  import { Audience } from "./visibility/audience.js";
12
12
 
13
- export { Audience, DefaultErrorOverlay, FormattedDate, FormattingScope, SoftrPwaHead, assertRouteAccess, checkAccess, defineComments, defineIntegration, defineMutation, defineQuery, defineVisibility, defineWorkflow, formatDate, formatDateTime, formatNumber, getSoftrContext, guardRoute, initialSoftrContext, isAccessError, isAlreadyAuthenticatedError, isAuthorized, isForbiddenError, isUnauthenticatedError, softrAuthMiddleware, softrMcpMiddleware, useCurrentUser, useFileUpload, useFormatting, usePwaInstall, useUserTimezone };
13
+ export { Audience, DefaultErrorOverlay, FormattedDate, FormattingScope, SoftrPwaHead, assertRouteAccess, checkAccess, defineIntegration, defineMutation, defineQuery, defineVisibility, defineWorkflow, formatDate, formatDateTime, formatNumber, getSoftrContext, guardRoute, initialSoftrContext, isAccessError, isAlreadyAuthenticatedError, isAuthorized, isForbiddenError, isUnauthenticatedError, softrAuthMiddleware, softrMcpMiddleware, useCurrentUser, useFileUpload, useFormatting, usePwaInstall, useUserTimezone };
package/dist/package.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region package.json
2
- var version = "0.0.63-alpha.0";
2
+ var version = "0.0.63";
3
3
 
4
4
  //#endregion
5
5
  export { version };
package/dist/pwa.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import * as react0 from "react";
1
+ import * as react3 from "react";
2
2
  import "@tanstack/react-start";
3
3
 
4
4
  //#region src/pwa.d.ts
@@ -23,7 +23,7 @@ import "@tanstack/react-start";
23
23
  * )
24
24
  * }
25
25
  */
26
- declare function SoftrPwaHead(): react0.FunctionComponentElement<react0.FragmentProps>;
26
+ declare function SoftrPwaHead(): react3.FunctionComponentElement<react3.FragmentProps>;
27
27
  type PwaPlatform = "ios" | "android" | "desktop";
28
28
  type PwaInstall = {
29
29
  available: false;
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, comments, ds, integration, upload, workflow };
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, comments, ds, integration, upload, workflow };
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.63-alpha.0",
3
+ "version": "0.0.63",
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.63-alpha.0
14
+ library_version: 0.0.61
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`, `defineComments`, `defineVisibility`, `guardRoute`, `assertRouteAccess`, `isAuthorized`, `checkAccess`, `Audience`, `useCurrentUser`, `useUserTimezone`, `FormattedDate`, `FormattingScope`, `useFormatting`, `formatDate`, `formatDateTime`, `formatNumber`, `SoftrPwaHead`, `usePwaInstall`, `getSoftrContext`, `initialSoftrContext`, `softrAuthMiddleware`, the error predicates, and every type |
33
- | `@softr/sdk/server` | Server only | `ds`, `auth`, `workflow`, `integration`, `comments` |
34
- | `@softr/sdk/client` | Browser only | `useCommentComposer` |
32
+ | `@softr/sdk` | Both | `defineQuery`, `defineMutation`, `defineVisibility`, `guardRoute`, `assertRouteAccess`, `isAuthorized`, `checkAccess`, `Audience`, `useCurrentUser`, `useUserTimezone`, `FormattedDate`, `FormattingScope`, `useFormatting`, `formatDate`, `formatDateTime`, `formatNumber`, `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
@@ -50,7 +50,6 @@ Each sub-skill stands alone for its task and repeats the boundary above, so most
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
  | Show a date, a time or a number | [formatting/SKILL.md](./formatting/SKILL.md) |
53
- | Add comments to a record | [comments/SKILL.md](./comments/SKILL.md) |
54
53
 
55
54
  ## Quick Decision Tree
56
55
 
@@ -91,9 +90,6 @@ Adding an install button, or making the app installable?
91
90
  Showing a date, a time or a number on a page?
92
91
  load softr-sdk/formatting
93
92
 
94
- Letting visitors comment on a record?
95
- load softr-sdk/comments
96
-
97
93
  Writing a server function, loader, or middleware in general?
98
94
  not a Softr concern. Use the TanStack Start skills.
99
95
  ```
@@ -16,7 +16,7 @@ description: >-
16
16
  metadata:
17
17
  type: sub-skill
18
18
  library: softr-sdk
19
- library_version: 0.0.63-alpha.0
19
+ library_version: 0.0.61
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.63-alpha.0
15
+ library_version: 0.0.61
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.
@@ -9,7 +9,7 @@ description: >-
9
9
  metadata:
10
10
  type: sub-skill
11
11
  library: softr-sdk
12
- library_version: 0.0.63-alpha.0
12
+ library_version: 0.0.61
13
13
  ---
14
14
 
15
15
  # The current user
@@ -10,7 +10,7 @@ description: >-
10
10
  metadata:
11
11
  type: sub-skill
12
12
  library: softr-sdk
13
- library_version: 0.0.63-alpha.0
13
+ library_version: 0.0.61
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 // clean URL, no internal query params
79
- filename: string // original filename
80
- id: string // file id extracted from the upload response
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.63-alpha.0
13
+ library_version: 0.0.61
14
14
  ---
15
15
 
16
16
  # Dates, times and numbers
@@ -10,7 +10,7 @@ description: >-
10
10
  metadata:
11
11
  type: sub-skill
12
12
  library: softr-sdk
13
- library_version: 0.0.63-alpha.0
13
+ library_version: 0.0.61
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.63-alpha.0
12
+ library_version: 0.0.61
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.
@@ -9,7 +9,7 @@ description: >-
9
9
  metadata:
10
10
  type: sub-skill
11
11
  library: softr-sdk
12
- library_version: 0.0.63-alpha.0
12
+ library_version: 0.0.61
13
13
  ---
14
14
 
15
15
  # Installing the app
@@ -11,7 +11,7 @@ description: >-
11
11
  metadata:
12
12
  type: sub-skill
13
13
  library: softr-sdk
14
- library_version: 0.0.63-alpha.0
14
+ library_version: 0.0.61
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,7 +13,7 @@ description: >-
13
13
  metadata:
14
14
  type: sub-skill
15
15
  library: softr-sdk
16
- library_version: 0.0.63-alpha.0
16
+ library_version: 0.0.61
17
17
  ---
18
18
 
19
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.
@@ -9,7 +9,7 @@ description: >-
9
9
  metadata:
10
10
  type: sub-skill
11
11
  library: softr-sdk
12
- library_version: 0.0.63-alpha.0
12
+ library_version: 0.0.61
13
13
  ---
14
14
 
15
15
  **Boundary.** `Audience` and `defineVisibility` come from `@softr/sdk` and work anywhere.
@@ -13,7 +13,7 @@ description: >-
13
13
  metadata:
14
14
  type: sub-skill
15
15
  library: softr-sdk
16
- library_version: 0.0.63-alpha.0
16
+ library_version: 0.0.61
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.63-alpha.0
12
+ library_version: 0.0.61
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 };