@softr/sdk 0.0.65 → 0.0.67
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/package.js +1 -1
- package/package.json +1 -1
- package/skills/softr-sdk/SKILL.md +1 -1
- 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 +1 -1
- package/skills/softr-sdk/formatting/SKILL.md +1 -1
- package/skills/softr-sdk/integrations/SKILL.md +38 -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 +3 -2
- package/skills/softr-sdk/region-visibility/SKILL.md +1 -1
- package/skills/softr-sdk/routes-and-visibility/SKILL.md +3 -2
- package/skills/softr-sdk/workflows/SKILL.md +1 -1
package/dist/package.js
CHANGED
package/package.json
CHANGED
|
@@ -19,7 +19,7 @@ description: >-
|
|
|
19
19
|
metadata:
|
|
20
20
|
type: sub-skill
|
|
21
21
|
library: softr-sdk
|
|
22
|
-
library_version: 0.0.
|
|
22
|
+
library_version: 0.0.67
|
|
23
23
|
---
|
|
24
24
|
|
|
25
25
|
**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.67
|
|
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.67
|
|
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.
|
|
@@ -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.67
|
|
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.
|
|
@@ -127,6 +127,43 @@ const sendSlackMessage = createServerFn({ method: 'POST' })
|
|
|
127
127
|
|
|
128
128
|
Do not add an `Authorization` key to `headers` — Softr injects the integration's credentials automatically.
|
|
129
129
|
|
|
130
|
+
## Calling an AI model
|
|
131
|
+
|
|
132
|
+
A button on one record that hands its fields to the model and shows the answer is the `ai-action` pattern:
|
|
133
|
+
it carries this call and the model id, so write the call by hand only for another shape — a batch, a chat,
|
|
134
|
+
a field the model fills on create. An AI integration is called like any other. For `ANTHROPIC_AI`, the action is `POST` on
|
|
135
|
+
`https://api.anthropic.com/v1/messages`, the request carries the `anthropic-version` header and a body of
|
|
136
|
+
`model`, `max_tokens`, `system` and `messages`, and the answer's text is in `content[].text`:
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
const askClaude = defineIntegration({
|
|
140
|
+
id: 'askClaude',
|
|
141
|
+
integrationId: '<the ANTHROPIC_AI integration id from the attached integrations>',
|
|
142
|
+
method: 'POST',
|
|
143
|
+
url: 'https://api.anthropic.com/v1/messages',
|
|
144
|
+
permissions: { userGroupTypes: ['LOGGED_IN_USERS'] },
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
const claude = integration.createFetcher(askClaude)
|
|
148
|
+
const res = await claude({
|
|
149
|
+
headers: { 'Content-Type': 'application/json', 'anthropic-version': '2023-06-01' },
|
|
150
|
+
body: JSON.stringify({
|
|
151
|
+
model: 'claude-opus-5-5',
|
|
152
|
+
max_tokens: 1024,
|
|
153
|
+
system: 'You write a short briefing for a sales team. Use only the facts given.',
|
|
154
|
+
messages: [{ role: 'user', content: facts }],
|
|
155
|
+
}),
|
|
156
|
+
})
|
|
157
|
+
if (!res.ok) throw new Error(`AI error: ${res.status} ${await res.text()}`)
|
|
158
|
+
const body = (await res.json()) as { content: Array<{ type: string; text?: string }> }
|
|
159
|
+
const text = body.content.flatMap((block) => (block.type === 'text' && block.text ? [block.text] : [])).join('')
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**Use the model id above as it is written here.** Model ids are not derivable: one spelled from memory
|
|
163
|
+
(`claude-3-5-…`, `claude-sonnet-4-…`) names a model that no longer answers, and the error only shows up when
|
|
164
|
+
the button is pressed. `claude-opus-5-5` is the current default; `claude-sonnet-5-5` is the cheaper one for a
|
|
165
|
+
short summary.
|
|
166
|
+
|
|
130
167
|
## Base URLs by integration type
|
|
131
168
|
|
|
132
169
|
Match the `integrationType` from the attached integrations section to find the base URL:
|
|
@@ -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.67
|
|
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.67
|
|
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.
|
|
16
|
+
library_version: 0.0.67
|
|
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.
|
|
@@ -56,7 +56,8 @@ const publishedPosts = defineQuery({
|
|
|
56
56
|
- `permissions` declares who may run the query, and the SDK enforces it:
|
|
57
57
|
- `{ userGroupTypes: ['NON_LOGGED_IN_USERS', 'LOGGED_IN_USERS'] }`: everyone, signed out included. `customGroups` narrows only the signed-in half.
|
|
58
58
|
- `{ userGroupTypes: ['NON_LOGGED_IN_USERS'] }`: signed-out visitors only.
|
|
59
|
-
- `{ userGroupTypes: ['LOGGED_IN_USERS'] }`: any signed-in visitor, narrowed to particular groups with `customGroups: ['00000000-0000-0000-0000-00000000000a']`.
|
|
59
|
+
- `{ userGroupTypes: ['LOGGED_IN_USERS'] }`: any signed-in visitor, narrowed to particular groups with `customGroups: ['00000000-0000-0000-0000-00000000000a']`. `customGroups` is added to `userGroupTypes`, never written in place of it.
|
|
60
|
+
- Write each group id as a literal in `permissions`. An id taken from a `const` is a lint error, as it is in a route's visibility.
|
|
60
61
|
- Write the object inline in the `defineQuery` call. Passing the declaration or its `fields` through a variable, or spreading one in, widens the field ids to `string` and the types stop checking.
|
|
61
62
|
|
|
62
63
|
A query fixes the table and the columns, not the rows: filters, sorting and paging stay at the call site, because a list screen changes them as the user types. Declare as many queries over one datasource as the app needs, each carrying the fields its own screen touches.
|
|
@@ -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.67
|
|
17
17
|
---
|
|
18
18
|
|
|
19
19
|
**Boundary.** `defineVisibility`, the access functions and the error predicates come from `@softr/sdk` and work anywhere.
|
|
@@ -49,6 +49,7 @@ Four constraints on that shape, because Softr reads the file rather than running
|
|
|
49
49
|
- The call must initialise a top-level `const`.
|
|
50
50
|
- The import must be a direct named import from `@softr/sdk`.
|
|
51
51
|
- The route guards itself in `beforeLoad`, naming a rule declared in the same file. A rule imported from elsewhere is rejected.
|
|
52
|
+
- Every value inside the literal is written there too. A group id taken from a `const`, a spread or an import is rejected, even when two routes share it: repeat the id on each.
|
|
52
53
|
- Never declare on `__root.tsx`. The root cannot carry an audience, so a declaration there would gate nothing while looking like it does. Softr rejects it. Put the rule on a layout below the root instead.
|
|
53
54
|
|
|
54
55
|
`userGroupTypes` is a set, so a rule names one audience or several:
|
|
@@ -68,7 +69,7 @@ defineVisibility({
|
|
|
68
69
|
```
|
|
69
70
|
|
|
70
71
|
Everyone is both audiences, as in the first line above. A set names each audience at most once and
|
|
71
|
-
is never empty — the type and the build both reject one that does not. `customGroups` narrows
|
|
72
|
+
is never empty — the type and the build both reject one that does not. `customGroups` never stands alone: it narrows the `LOGGED_IN_USERS` half of the set, so the rule still names that half, and one without `userGroupTypes` is a type error. Absent or empty it
|
|
72
73
|
means **any** signed-in visitor, not "nobody".
|
|
73
74
|
|
|
74
75
|
Take every id in `customGroups` from `docs/user-groups.md`, which lists each group the app has with its name and id. An id the app does not have is a type error.
|
|
@@ -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.67
|
|
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.
|